默认情况下,Spring 会对 Error 或 RuntimeException 异常进行事务回滚,而对于继承自 java.lang.Exception 的其他异常(如 IOException、TimeoutException 等)则不会进行回滚。解决这一问题,可通过将 @Transactional 注解中的 rollbackFor 属性设置为 Exception.class。另一个重要的失效场景是同一类中的方...
【Java】 @Transactional失效的几种场景
在使用 Spring 的 @Transactional 注解控制事务时,会遇到多种不生效的场景。首先,需要注意的是,如果数据库引擎不支持事务,无论 @Transactional 如何配置,都起不了作用。MySQL 从版本 5.5.5 开始,其默认存储引擎为 InnoDB,因此,若底层数据库引擎不支持事务,那么 @Transactional 的效果将无法实现。
其次,@Transactional 注解仅适用于 public 可见度的方法。若需要对非 public 方法进行事务控制,可以采用 AspectJ 代理模式。Spring 官方文档提示,当使用代理时,应仅对具有 public 可见度的方法应用 @Transactional。若违反此规则,尽管不会抛出错误,但注解方法将不遵循配置的事务设置。
再者,当在业务方法中遇到 try-catch 异常时,事务不会被自动回滚。Spring 的事务管理在方法调用之前开始,之后结束,事务是否执行取决于是否抛出 runtime 异常。若抛出 runtime exception 并未被捕获,事务将回滚。处理这种情况的一种方法是通过 @Transactional(rollbackFor = Exception.class) 属性,或者在 catch 块中手动执行回滚操作。
默认情况下,Spring 会对 Error 或 RuntimeException 异常进行事务回滚,而对于继承自 java.lang.Exception 的其他异常(如 IOException、TimeoutException 等)则不会进行回滚。解决这一问题,可通过将 @Transactional 注解中的 rollbackFor 属性设置为 Exception.class。
另一个重要的失效场景是同一类中的方法调用。在开发过程中,我们常常需要在同一个类中调用其他方法,即使这两个方法在类中分别使用了 @Transactional 注解,但只有当外部代码调用时,事务才由 Spring 代理管理。这意味着在同一个类内部的方法调用,即使有事务注解,也可能导致事务控制失效。2024-11-20