以前、com.TestTransactionクラスにメソッドupdateRecord()を作成しました。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ファイル内(春の構成ファイル)
<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
}
}
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.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>
誰かが何が起こっているのかについて何か考えを与えることができますか?メソッド(トランザクション)がループ内で呼び出されたときに、1つの更新をロールバックすることは可能ですか?