如何界定回滚事务被称为Spring AOP实现一个循环内?(How to define rollba

2019-09-28 19:35发布

此前我已经创建了一个方法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
   }
}

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>

谁能给正在发生的事情的任何想法? 是否可以回滚一个更新时的方法(事务)被称为一个循环里面?

Answer 1:

这可能是我碰到的情况下这个问题 。 同一个类中调用不通过代理服务器和你的切入点逻辑被忽略。



Answer 2:

因为春天只在方法调用的支持方面来了解你的春天将无法拦截doUpdateRecord因为它不叫克服弹簧所管理的bean的实例。 为了使方面的工作,doUpdateRecord需要调用克服弹簧bean实例,因为只有这样会弹出拦截方法调用并插入事务性的东西。

无论你注入TestTransaction春bean实例为测试交易本身和参考,当你调用doUpdateRecord(不知道这是否会工作),或者你移动doUpdateRecord代码到另一个bean,并呼吁针对豆。



文章来源: How to define rollback transactions which are called inside of a loop with spring aop?