设置默认回滚规则后,事务回滚不适用于 Propagation.REQUIRES_NEW
Transaction rollback not working with Propagation.REQUIRES_NEW when default rollback rule is set
我使用 MyBatis 3.4.5 和 Spring 4.1.6。我检查了 abstract class GenericException(扩展了 Exception)和 CustomException(扩展了 GenericException)。我在 tx:
中为 GenericException 设置了默认回滚
<tx:advice id="txSetRollBackForCoreExceptionsAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" rollback-for="RuntimeException,xxx.exceptions.GenericException"/>
</tx:attributes>
</tx:advice>
Service1 中的方法:
@Override
public Long push(TimerState timerState) {
try {
return timerStatePushService.pushEvent(timerState);
}catch (Exception e) {
throw new TimerException(e.getMessage());
}
}
服务 2:
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Service
public class TimerStatePushServiceBean implements TimerStatePushService {
@Autowired
PushService pushService;
@Override
public Long pushEvent(TimerState timerState) throws GenericException {
return pushService.pushEventById(timerState.getId());
}
如果 pushService 抛出 CustomException(它扩展了 GenericException),我会在 Service1 中捕获 UnexpectedRollbackException。在跟踪日志中我看到:
12:42:48.677 TRACE {pool-15-thread-1} [o.s.t.i.RuleBasedTransactionAttribute] : Applying rules to determine whether transaction should rollback on xxx.exceptions.CustomException
12:42:48.677 TRACE {pool-15-thread-1} [o.s.t.i.RuleBasedTransactionAttribute] : Winning rollback rule is: null
12:42:48.677 TRACE {pool-15-thread-1} [o.s.t.i.RuleBasedTransactionAttribute] : No relevant rollback rule found: applying default rules
12:42:48.677 DEBUG {pool-15-thread-1} [o.s.j.d.DataSourceTransactionManager] : Global transaction is marked as rollback-only but transactional code requested commit
如果我设置 "rollbackFor = GenericException.class" - 没问题:
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = GenericException.class)
@Service
public class TimerStatePushServiceBean implements TimerStatePushService {
@Autowired
PushService pushService;
@Override
public Long pushEvent(TimerState timerState) throws GenericException {
return pushService.pushEventById(timerState.getId());
}
如果我在方法 "pushEvent" 中抛出 CustomException 而没有设置 rollbackFor - 一切正常:
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Service
public class TimerStatePushServiceBean implements TimerStatePushService {
@Autowired
PushService pushService;
@Override
public Long pushEvent(TimerState timerState) throws GenericException {
throw new CustomException("msg");
}
我不明白这是怎么回事。有关信息:我需要在 TimerStatePushService 中回滚事务,但不要在 Service1 中回滚事务。
我已经解决了问题。我有两个模块:core
和 manager
。对于 core
设置:
<aop:config>
<aop:pointcut expression="within(xxx.core..*) && @within(org.springframework.stereotype.Service)"
id="inCoreServiceCall"/>
<aop:advisor order="1"
advice-ref="txSetRollBackForCoreExceptionsAdvice"
pointcut-ref="inCoreServiceCall"/>
</aop:config>
PushService
在 core
模块中,另一个服务在 manager
模块中。
我为 manager
模块添加了设置。
我使用 MyBatis 3.4.5 和 Spring 4.1.6。我检查了 abstract class GenericException(扩展了 Exception)和 CustomException(扩展了 GenericException)。我在 tx:
中为 GenericException 设置了默认回滚<tx:advice id="txSetRollBackForCoreExceptionsAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" rollback-for="RuntimeException,xxx.exceptions.GenericException"/>
</tx:attributes>
</tx:advice>
Service1 中的方法:
@Override
public Long push(TimerState timerState) {
try {
return timerStatePushService.pushEvent(timerState);
}catch (Exception e) {
throw new TimerException(e.getMessage());
}
}
服务 2:
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Service
public class TimerStatePushServiceBean implements TimerStatePushService {
@Autowired
PushService pushService;
@Override
public Long pushEvent(TimerState timerState) throws GenericException {
return pushService.pushEventById(timerState.getId());
}
如果 pushService 抛出 CustomException(它扩展了 GenericException),我会在 Service1 中捕获 UnexpectedRollbackException。在跟踪日志中我看到:
12:42:48.677 TRACE {pool-15-thread-1} [o.s.t.i.RuleBasedTransactionAttribute] : Applying rules to determine whether transaction should rollback on xxx.exceptions.CustomException
12:42:48.677 TRACE {pool-15-thread-1} [o.s.t.i.RuleBasedTransactionAttribute] : Winning rollback rule is: null
12:42:48.677 TRACE {pool-15-thread-1} [o.s.t.i.RuleBasedTransactionAttribute] : No relevant rollback rule found: applying default rules
12:42:48.677 DEBUG {pool-15-thread-1} [o.s.j.d.DataSourceTransactionManager] : Global transaction is marked as rollback-only but transactional code requested commit
如果我设置 "rollbackFor = GenericException.class" - 没问题:
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = GenericException.class)
@Service
public class TimerStatePushServiceBean implements TimerStatePushService {
@Autowired
PushService pushService;
@Override
public Long pushEvent(TimerState timerState) throws GenericException {
return pushService.pushEventById(timerState.getId());
}
如果我在方法 "pushEvent" 中抛出 CustomException 而没有设置 rollbackFor - 一切正常:
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Service
public class TimerStatePushServiceBean implements TimerStatePushService {
@Autowired
PushService pushService;
@Override
public Long pushEvent(TimerState timerState) throws GenericException {
throw new CustomException("msg");
}
我不明白这是怎么回事。有关信息:我需要在 TimerStatePushService 中回滚事务,但不要在 Service1 中回滚事务。
我已经解决了问题。我有两个模块:core
和 manager
。对于 core
设置:
<aop:config>
<aop:pointcut expression="within(xxx.core..*) && @within(org.springframework.stereotype.Service)"
id="inCoreServiceCall"/>
<aop:advisor order="1"
advice-ref="txSetRollBackForCoreExceptionsAdvice"
pointcut-ref="inCoreServiceCall"/>
</aop:config>
PushService
在 core
模块中,另一个服务在 manager
模块中。
我为 manager
模块添加了设置。