【发布时间】:2020-10-01 12:30:32
【问题描述】:
我有一个可以抛出 NullPointerException 的方法。该方法标记为@Transactional。
我的代码结构如下:
public void outer() {
try {
inner();
} catch (Exception e) {
// exception caught
}
}
@Transactional
public void inner() {
database.saveStuff();
throw new NullPointerException();
}
运行上述代码后,inner() 内部的数据库更新不会回滚。什么可能导致这样的问题?
根据我的理解,如果异常对注释“可见”,则应回滚数据库操作。在这种情况下意味着inner() 方法被标记为@Transactional 并抛出异常而不是捕获它。
可能还值得一提的是,方法 outer() 也在另一个 @Transactional 方法中调用,而该方法又在 try catch 中调用。但是,该方法看不到异常,因为它被捕获在 outer() 中,因此根据我的理解,它应该无关紧要。
我试图在网上搜索答案,但所有答案似乎都是关于已检查的异常(例如java.lang.Exception)不会自动回滚。因为NullPointerException 是RuntimeException 的子类,所以这里不应该成为问题。
我的团队中也有人建议使用这组注释,但没有任何区别:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(rollbackFor=Exception.class, isolation=Isolation.READ_COMMITTED)
【问题讨论】:
标签: java spring transactions