设置默认回滚规则时,事务回滚不适用于Propagation.REQUIRES_NEW

时间:2018-07-11 09:53:12

标签: java spring spring-transactions rollback

我使用MyBatis 3.4.5和Spring 4.1.6。我检查了抽象类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());
    }
}

Service2:

@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());
}

如果我在没有设置rollbackFor的情况下将Meetodd“ pushEvent”中抛出CustomException-一切正常:

@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中进行回滚事务。

1 个答案:

答案 0 :(得分:0)

我解决了问题。我有两个模块:核心和经理。对于核心已设置:

<aop:config>
        <aop:pointcut expression="within(xxx.core..*) &amp;&amp; @within(org.springframework.stereotype.Service)" id="inCoreServiceCall"/>
        <aop:advisor order="1" advice-ref="txSetRollBackForCoreExceptionsAdvice" pointcut-ref="inCoreServiceCall"/>
    </aop:config>

PushService在核心模块中,另一个服务在管理器模块中。 我添加了管理器模块的设置。