SPRING声明式事务,不写rollback-for的问题

问题疑惑

阿里编码规范按照 IDE 插件的方式发布。插件检查结果中有这么一条:“Spring 事务需要设置 rollbackFor 属性或者显式调用 rollback 方法”。为什么需要设置 rollbackFor 属性呢?

解惑

简单来说,如果不设置 rollbackFor = Exception.class,则当方法抛出检查型异常时,数据库操作不会回滚。

举例来说,对于下面的代码:

1
2
3
4
5
@Transactional
public void demo() throws Exception {
this.userRepository.save(new User(USERNAME));
throw new Exception("No Rollback");
}

执行完毕之后,数据库中会增加一条 user 记录。如果你希望在方法抛出检查型异常后触发数据库回滚,那你需要这样写:

1
2
3
4
5
@Transactional(rollbackFor = Exception.class)
public void demo() throws Exception {
this.userRepository.save(new User(USERNAME));
throw new Exception("No Rollback");
}

如果你的方法没有声明异常,只会抛出运行时异常,则不需要设置 rollbackFor。运行时异常抛出后会触发事务回滚。

1
2
3
4
5
@Transactional
public void demo() {
this.userRepository.save(new User(USERNAME));
throw new RuntimeException("Rollback");
}

如果代码如上所示,则不会有新的 user 记录。因为数据库操作回滚了。

总结

如果方法会抛出检查型异常,则必须在方法中声明异常。因此,一般而言,如果方法没有声明异常,则不需要配置在 Spring 事务注解中配置 rollbackFor。

另外,我在阿里的 Java 编码规范里也没有找到关于设置 rollbackFor 的内容。因此,我的个人意见是方法不抛出检查型异常就不必设置 rollbackFor。

参考

编走编想