面试官问:列出@Transactional注解下,事务失效的七种场景

面试官问:列出@Transactional注解下,事务失效的七种场景
最新回答
战天傲刃

2026-01-15 10:19:46

@Transactional注解下,事务失效的七种场景:

  1. 异常被捕获后没有抛出

    当方法内部发生异常,并且该异常被捕获后没有再次抛出时,事务不会回滚。因为Spring默认只在未捕获的运行时异常(RuntimeException)和错误(Error)发生时回滚事务。

  2. 抛出非运行时异常

    如果方法抛出的是非RuntimeException类型的异常(如自定义异常),默认情况下事务也不会回滚。可以通过在@Transactional注解中指定rollbackFor属性来包含非运行时异常,使其能够触发事务回滚。

  3. 方法内部直接调用

    当在同一个类中,一个带有@Transactional注解的方法被另一个方法直接调用时,事务不会生效。这是因为Spring的事务管理是通过动态代理实现的,而直接调用不会经过代理对象,因此无法触发事务管理。解决方法是将当前类注入到自身,通过注入的代理对象来调用带有@Transactional注解的方法。

  4. 新开启一个线程

    在@Transactional注解的方法中新开启一个线程执行数据库操作,这些操作不会受到事务管理。因为Spring的事务管理是基于ThreadLocal将数据库连接绑定到当前线程的,新线程无法获取到绑定到父线程的事务连接。

  5. 注解到private方法上

    将@Transactional注解在private方法上是无效的。因为private方法无法被Spring的动态代理所拦截,因此无法生成事务管理的代理逻辑。通常,@Transactional注解应该应用于public方法上。

  6. 数据库本身不支持事务

    如果使用的数据库引擎不支持事务(如MySQL的MyISAM引擎),那么即使方法上标注了@Transactional注解,事务也不会生效。确保数据库引擎支持事务(如MySQL的InnoDB引擎)是使用Spring事务管理的前提。

  7. 事务传播属性设置错误

    事务的传播属性决定了事务的行为方式。如果设置了错误的事务传播属性(如PROPAGATION_NOT_SUPPORTED),则会导致事务失效。例如,PROPAGATION_NOT_SUPPORTED表示以非事务的方式执行操作,如果当前存在事务,则将当前事务挂起。这会导致即使方法上标注了@Transactional注解,事务也不会生效。

以上是@Transactional注解下事务失效的七种常见场景,了解这些场景有助于避免在实际开发中遇到事务管理相关的问题。