spring配置事务传播特性为REQUIRED,即如果有就加入。如果是在业务中有记录日志等操作,用此特性,则发生回滚后日志也记录不上。
将记录日志的方法配置成REQUIRED_NEW,无论如何都会新开启一个事务,并将之前的事务挂起。这样如果之前的事务回滚,不会影响这个事务。
REQUIRED_NEW的方法不能和REQUIRED的方法在同一个类中,否则不生效(网上是这样说的,具体没测试)
例如:
事务切在a方法,a调用b方法(记录日志)。如果不单独设置事务,那么异常后a,b都回滚。
如果a方法设置事务REQUIRED,b方法设置事务REQUIRED_NEW,那么异常后a回滚,b不回滚。(b方法需要在另一个业务类中)
配置代码如下:
<!-- 配置事务特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="process*" propagation="REQUIRED"/>
<tx:method name="newSaveOrUpdate*" propagation="REQUIRES_NEW"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 配置那些类的方法进行事务管理 -->
<aop:config>
<aop:pointcut id="allManagerMethod" expression="execution(* com.ibm.service..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
</aop:config>
如果手动抛出异常,需要抛出runtimeException才能回滚。如果抛出exception则不会回滚。