#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 {
}
}