Ранее я создал метод updateRecord() в классе com.TestTransaction. Метод updateRecord() имеет цикл for для вставки значений в базу данных. Если внутри цикла возникает какое-либо исключение, все вставленные значения будут откатываться. Это отлично работает, и код выглядит следующим образом:
Внутри файла класса java
public class com.TestTransaction{
...
//this is a big transaction
public void updateRecord(){
for(int i=0;i<5;i++){
//insert value to database...
//...if a runtime exception thrown here,
//updateA() method will rollback as a whole transaction,
//so all updates which were done inside the loop will rollback
}
}
...
}
Внутри файла config.xml (файл конфигурации Spring)
<bean id="masterTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource" ref="masterDataSource" />
<property name="nestedTransactionAllowed" value="true" />
</bean>
...
<aop:config proxy-target-class="true">
<aop:pointcut id="testTransactionTX" expression="execution(* com.TestTransaction.*(..))"/>
<aop:advisor pointcut-ref="testTransactionTX" advice-ref="defaultTxAdvice"/>
</aop:config>
...
<tx:advice id="defaultTxAdvice" transaction-manager="masterTxManager">
<tx:attributes>
<tx:method name="update*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
Затем я решил сделать код внутри цикла метода updateRecord() отдельным методом doUpdateRecord(). Таким образом, когда doUpdateRecord() выдает исключение RuntimeException, он откатывает только этот doUpdateRecord(), и все предыдущие обновления будут зафиксированы. Но похоже, что откатиться не удается.
Код, как показано ниже:
public class com.TestTransaction{
...
//this is no longer a big transaction
public void updateRecord(){
for(int i=0;i<5;i++){
//every doUpdateRecord() call will start a new transaction
doUpdateRecord();
}
}
//this is a transaction
public void doUpdateRecord(){
//insert value to database...
//...if a runtime exception thrown here,
//it only rollback this method
}
}
Конфигурационный файл весны:
<bean id="masterTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource" ref="masterDataSource" />
<property name="nestedTransactionAllowed" value="true" />
</bean>
...
<aop:config proxy-target-class="true">
<aop:pointcut id="testTransactionTX" expression="execution(* com.TestTransaction.doUpdateRecord(..))"/>
<aop:advisor pointcut-ref="testTransactionTX" advice-ref="defaultTxAdvice"/>
</aop:config>
...
<tx:advice id="defaultTxAdvice" transaction-manager="masterTxManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRES_NEW"/>
</tx:attributes>
</tx:advice>
Может ли кто-нибудь дать какие-либо идеи о том, что происходит? Можно ли откатить одно обновление при вызове метода (транзакции) внутри цикла?