Spring事务异常回滚三种方案——捕获异常不抛出就不会回滚

下面这种情况,使用了catch捕获了异常,spring事务不会发生回滚

try {
    userDao.save(user);
    userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
    logger.info("能力开通接口,开户异常,异常信息:"+e);
}

默认spring事务只在发生未被捕获的RuntimeException时才回滚。
springaop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获RuntimeException的异常,但可以通过配置来捕获特定的异常并回滚;

解决方式

1:通过throw new RuntimeException();抛出运行时异常

try {
    userDao.save(user);
    userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
    logger.info("能力开通接口,开户异常,异常信息:"+e);
    throw new RuntimeException();
}

2:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();,手动回滚

try {
    userDao.save(user);
    userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
    logger.info("能力开通接口,开户异常,异常信息:"+e);
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}

3:还有一种方法,而且是推荐方法:在这个代码所在的方法上加上rollbackFor ,
形如:@Transactional(readOnly = true, rollbackFor = Exception.class)。这样也可以回滚。

@Transactional(readOnly = true, rollbackFor = Exception.class)
public void getPermissionsByRoleId(long roleId) {
try {
    dao.getPermissionsByRoleId(roleId);
    userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
    logger.info("能力开通接口,开户异常,异常信息:"+e);
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}

 

你可能感兴趣的:(大厂任性挑,springBoot,Spring事务,回滚,异常)