首先了解一下异常的组成:
RuntimeException()
例如:数组越界异常、空指针异常、(我们在编写之后不会提示让 try catch
的异常、代码编写错误导致,可避免)
非RuntimeException()
例如: IO异常、(会提示try catch
的异常,不是代码编写错误导致的,只能抛出)
unchecked异常
:RuntimeException
+ Error
checked异常
:非RuntimeException()
Spring通过异常进行事务回滚的机制:
unchecked
异常时候回滚,checked
异常的时候不会回滚;
service
层捕获异常并打印日志,这时我们的所有异常都会被认为成checked
异常。
try catch
后捕获了异常,事务不会回滚,
如果不得不在service
层写try catch
需要catch
后 throw new RuntimeException
让事务回滚;
因为要保证当前方法具有返回值,在前端界面展示操作状态。
所以我们service
层在添加了try catch
日志打印后,抛出的runtime
类异常需要在controller
层进行捕获,捕获之后,在catch
中编写操作失败后返回值的信息。
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
throw new RuntimeException();
}
在service
层方法的catch
语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
语句,手动回滚,这样上层就无需去处理异常了
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
不依赖于Spring的异常捕获机制进行事务回滚,通过手动的session.rollback
进行异常捕获后回滚事务也可。