spring事务,为什么运行时异常回滚?Exception不回滚?

317 阅读2分钟

在Spring事务管理中,默认情况下运行时异常(RuntimeException)会导致事务回滚,而受检异常(checked exceptions,如Exception的直接子类)则不会导致事务回滚。这种设计有其特定的原因:

运行时异常回滚的原因

  1. 运行时异常通常表示程序错误:RuntimeException及其子类(如NullPointerException、IllegalArgumentException等)通常表示程序中的严重错误或Bug,这类错误在正常运行的程序中不应该出现。
  2. 不可恢复性:运行时异常往往是不可预测的,且难以从中恢复,因此回滚事务是更安全的选择。
  3. 无需显式捕获:Java不强制要求捕获运行时异常,它们可以在调用栈中传播,Spring利用这一特性来管理事务。

受检异常不回滚的原因

  1. 受检异常代表可预见的错误情况:如IOException、SQLException等,它们通常代表可预见且可能可以处理的错误情况。
  2. 业务逻辑考量:有些业务逻辑可能会抛出受检异常,但这不一定意味着事务应该回滚。例如,一个文件不存在的异常可能只需要记录日志,而不需要回滚整个事务。
  3. 开发者能够明确处理:Java强制要求开发者显式捕获或声明受检异常,这意味着开发者有机会决定如何处理这些异常。

如何自定义回滚行为

如果你需要改变默认行为,可以使用以下方式:

  1. 使用@Transactional注解的rollbackFornoRollbackFor属性:
@Transactional(rollbackFor = Exception.class)  // 使所有异常都回滚
public void someMethod() {
    // 方法内容
}

@Transactional(noRollbackFor = RuntimeException.class)  // 使运行时异常也不回滚
public void anotherMethod() {
    // 方法内容
}
  1. 在XML配置中:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*" rollback-for="Exception"/>
    </tx:attributes>
</tx:advice>

希望这个解释能帮助你理解Spring事务管理的默认行为!如果有任何其他关于Spring事务的问题,请随时提出。

service抛出运行时异常,但是controller捕获了这个运行时异常,service事务还会提交吗?

spring事务是否回滚,和controller没有关系。

该提交就提交。

该回滚就回滚。