Возможно ли создать собственные запросы, которые используют существующую транзакцию, созданную с помощью @Transactional? Большинство вопросов здесь, похоже, касаются создания собственных запросов вообще. Кроме того, ответы, например, от Spring + Hibernate Transaction -- Native SQL rollback failure, предполагают, что это может быть невозможно.Spring & Hibernate - Сделать собственные запросы запущены в той же транзакции, что и @Transactional
Что я делаю, чтобы проверить изоляцию, это запустить некоторые удаления и добавить точку останова для исследования базы данных.
Вот что я пытался до сих пор:
@Transactional(value = "someManager")
public class SpringJpaSomeDao implements SomeDao {
@PersistenceContext(unitName = "someUnit")
@Qualifier("entityManagerFactorySome")
private EntityManager em;
@Resource
@Qualifier("someManager")
private PlatformTransactionManager transactionManager;
@Override
@Transactional(value = "someManager", propagation = Propagation.SUPPORTS)
public void runNative(String sql){
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
em.createNativeQuery(sql).executeUpdate();
}
});
}
Некоторая часть persistence.xml
<persistence-unit name="someUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>java:comp/env/jdbc/someDS</non-jta-data-source>
<!-- some classes here -->
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<!-- some dialect -->
</properties>
</persistence-unit>
код вызывается из какой-то контроллер, который также имеет @Transactional аннотаций, дающие ему удалений в Дао.
@Transactional(value = "someManager", propagation = Propagation.SUPPORTS)
public void deleteEntireDatabase() {
List<String> deletions = new ArrayList<>();
deletions.add("DELETE FROM something;");
for (String currentDeletion : deletions) {
someDao.runNative(currentDeletion);
}
}
@Override
@Transactional(value = "someManager", propagation = Propagation.REQUIRES_NEW, rollbackFor = {Exception.class})
public void deleteAndFill(JobExecutionProgress progress) {
deleteEntireDatabase();
// more code
}
Выдержка из весенне-dao.xml:
<tx:annotation-driven />
<bean id="entityManagerFactorySome" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="someDataSource" />
<property name="persistenceUnitName" value="someUnit" />
<property name="jpaProperties">
<props>
<!-- some dialect -->
</props>
</property>
</bean>
<bean id="someDao" class="xyz.model.controller.SpringJpaSomeDao"/>
<bean id="someManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactorySome" />
<qualifier value="someManager"></qualifier>
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
Конечно, я также попробовал некоторые вариации, такие как различные Propagations, и используя EntityManager, полученный из других источников:
EntityManagerFactory emf = ((JpaTransactionManager) transactionManager).getEntityManagerFactory();
EntityManager em2 = EntityManagerFactoryUtils.getTransactionalEntityManager(emf);
Теперь, что я буду делать, если все остальное не удается, это управление транзакциями вручную.
Это что-то, что сработало для одного из ваших приложений, или неизвестно, может ли это быть проблемой установки?
Кстати, для полноты я должен упомянуть, что метод delete также содержал инструкции alter table для сброса auto_increment. –