前言
spring 事物管理默认配置下如果,service中try{}catch{}中发生了异常,事物是不会回滚的。
原因
Spring默认情况下会对运行期捕获到的RunTimeException进行事务回滚。
例如
if(user){
try {
userDao.save(user);
} catch (Exception e) {
}
}
解决方法
方法1
在catch中抛出运行时异常供spring捕获
if(user){
try {
userDao.save(user);
} catch (Exception e) {
throw new RuntimeException();
}
}
方法2
在catch中手动回滚事物,现在在用
if(user){
try {
userDao.save(user);
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
https://my.oschina.net/u/3714931/blog/1580753
方法3
配置@Transactional的参数
@Transactional(rollbackFor=Exception.class)
propagation:事务传播性设置,Propagation枚举类型。Spring支持的事务传播属性包括7种:
PROPAGATION_MANDATORY:方法必须在事务中执行,否则抛出异常。
PROPAGATION_NESTED:使方法运行在嵌套事务中,否则和PROPAGATION_REQUIRED一样。
PROPAGATION_NEVER :当前方法永远不在事务中运行,否则抛出异常。
PROPAGATION_NOT_SUPPORTED:定义为当前事务不支持的方法,在该方法执行期间正在运行的事务会被暂停
PROPAGATION_REQUIRED:当前的方法必须运行在事务中,如果没有事务就新建一个事务。新事务和方法一起开始,随着方法返回或者抛出异常时终止。
PROPAGATION_REQUIRED_NEW :当前方法必须新建一个事务,如果当前的事务正在运行则暂停。
PROPAGATION_SUPPORTS :规定当前方法支持当前事务,但是如果没有事务在运行就使用非事务方法执行。
isolation:事务隔离性级别设置,Isolation枚举类型
ISOLATION_DEFAULT :使用数据库默认的隔离级别
ISOLATION_COMMITTED:允许其他事务已经提交的更新(防止脏读取)
ISOLATION_READ_UNCOMMITTED:允许读取其他事务未提交的更新,会导致三个缺陷发生。执行速度最快
ISOLATION_REPEATABLE_READ :除非事务自身更改了数据,否则事务多次读取的数据相同(防止脏数据,多次重复读取)
ISOLATION_SERIALIZABLE:隔离级别最高,可以防止三个缺陷,但是速度最慢,影响性能。
readOnly:读写性事务,只读性事务,布尔型
timeout:超时时间,单位秒
rollbackFor:一组异常类的实例,遇到时必须进行回滚
rollbackForClassname:一组异常类的名字,遇到时必须进行回滚
noRollbackFor:一组异常类的实例,遇到时必须不回滚
noRollbackForClassname:一组异常类的名字,遇到时必须不回滚