How to define rollback transactions which are called inside of a loop with spring aop?

百般思念 提交于 2019-12-11 04:09:38

问题


Previously I have created a method updateRecord() in com.TestTransaction class. The updateRecord() method has a for loop to insert values into database. If there is any exception thrown inside the loop all the inserted values will rollback. This works fine and code is like below:

Inside the java class file

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
      }
   }
   ...
}

Inside config.xml file (Spring config file)

<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>

Then I decided to make code inside the loop of updateRecord() method as a separate method doUpdateRecord(). So that when doUpdateRecord() throws a RuntimeException, it only rolls back this doUpdateRecord() and all previous updates will be committed. But it seems that it fails to rollback.

Code as below:

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 config file:

<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>

Can anyone give any ideas of what is going on? Is it possible to rollback one update when a method (transaction) is called inside a loop?


回答1:


It's possibly the case I came across in this question. Calls within the same class don't pass through proxy and your pointcut logic is ignored.




回答2:


Because spring only supports aspects at method call that is knows about you spring will not be able to intercept that doUpdateRecord as it was not called against the spring managed instance of the bean. In order for the aspect to work that doUpdateRecord needs to be called against the spring bean instance because only then can spring intercept the method call and insert the transactional stuff.

Either you inject the spring bean instance of TestTransaction into test transaction itself and reference that when you call doUpdateRecord (not sure if this will work) or you move the doUpdateRecord code into another bean and call against that bean.



来源:https://stackoverflow.com/questions/8295366/how-to-define-rollback-transactions-which-are-called-inside-of-a-loop-with-sprin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!