Управление транзакциями Spring

#java #spring #transactions

#java #spring #транзакции

Вопрос:

В Java Spring я столкнулся с проблемой, касающейся отката транзакции.

Пример:

В моем коде есть 3 DAO (A, B, C). Все они расширяются JDBCTemplate :

 @Transaction(propagation=new_required)
public void serviceClassProc() throws Exception {
   A.db1();
   B.db2();
   C.db3();
}   
  

Теперь с помощью приведенного выше кода, если я создам исключение B.db2() , ничего не будет откатываться.

Теперь, если я изменю B.db2 следующим образом:

 @Transaction(propagation=nested,rollbackon=Exception.class)
public void db2() throws Exception{
...
throw new Exception();

}
  

А затем выполняется откат вызова serviceClassProc() , в B.db2 котором выполняется только транзакция.

Я хочу реализацию, в которой все транзакции внутри serviceClassProc() будут откатываться.

Вот 2 конфигурации, которые я использую:

 <bean id="bonddao" class="com.marki.bonds.staticdata.dao.MuniStaticDataDaoImpl"> <property name="dataSource" ref="c3p0DataSource" /> </bean> <bean id="dcldao" class="com.bonds.staticdata.dao.DclSettingsDaoImpl"> <constructor-arg ref="c3p0DataSource" /> </bean> <bean id="batchlogdao" class="com.bonds.staticdata.dao.MuniFeedHandlerBatchLogDaoImpl"> <constructor-arg ref="c3p0DataSource" /> </bean>

<bean id="bondsApplication" class="com.markit.bonds.staticdata.service.MuniRefDataSyncApp"> <property name="refdataService" ref="refDataSynchService" /> <property name="mailService" ref="mailSender"></property> <property name="batchLogger" ref="batchlogdao"></property> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="c3p0DataSource" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" />
  

Где я ошибаюсь? Неправильно ли иметь 3 DAO, расширяющих шаблон JDBC? Должны ли все они использовать один и тот же JdbcTemplate?

Комментарии:

1. Я не знаю, правильно ли это, но было бы логично поместить rollbackon=Exception.class в аннотации @Transaction, которая находится в методе serviceClassProc. Вы пробовали это?

2. Пожалуйста, опубликуйте конфигурацию xml для LocalContainerEntityManagerFactoryBean, JdbcTemplate, TransactionManager

3. Какие виды исключений генерируются? Обратите внимание, что по умолчанию Spring помечает txs для отката только в том случае, если исключение расширяется RuntimeException

Ответ №1:

Вы должны добавить rollbackon=Exception.class к аннотации вашего метода обслуживания и полностью удалить аннотацию транзакции из методов DAO. Это плохая идея иметь управление транзакциями на уровне DAO.

Комментарии:

1. Я пытался rollbackon=Exception.class но это не сработало. Где-то я чувствую, что все три расширения dao jdbctemplate означают, что все три транзакции имеют свое собственное соединение. Я не уверен, является ли это причиной проблемы.

Ответ №2:

вы также можете использовать : **org.springframework.transaction.interceptor.TransactionAspectSupport;**

вот пример, на котором вы можете с этим справиться:

 @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, transactionManager = "transactionManager")
public void messageHandler() {
            try {
                //TODO your own code

            } catch (Exception ex) { 
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            } finally { 

            } 

}