下面這種情況,使用了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)。這樣也可以回滾。
eg:
@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();
}
}