@transaction事务失效情况

@Transactional 注解在 Spring 框架中用于声明式事务管理。当事务未按预期工作时,通常称为事务失效。事务失效的场景可能包括以下几种:

  1. 方法不是 public
    @Transactional 只能应用于 public 方法。如果将其应用于 privateprotectedpackage-private 方法,事务将不会生效。

  2. 事务方法内部调用
    当同一个类中的非事务方法调用事务方法时,事务将不会生效。Spring AOP 代理无法拦截内部方法调用。

    public class MyService {
    
        public void nonTransactionalMethod() {
            transactionalMethod();  // 事务不会生效
        }
    
        @Transactional
        public void transactionalMethod() {
            // 事务逻辑
        }
    }
    
  3. 事务代理类型不正确
    默认情况下,Spring 使用 JDK 动态代理,这需要接口。如果类没有实现接口,Spring 将无法创建事务代理。使用 proxyTargetClass = true 可以启用 CGLIB 代理,它不需要接口。

    @EnableTransactionManagement(proxyTargetClass = true)
    
  4. 默认的事务管理器未配置
    如果项目中有多个事务管理器而未指定默认的事务管理器,事务可能会失效。需要明确指定事务管理器。

    @Transactional(transactionManager = "yourTransactionManager")
    
  5. Propagation 设置不当
    事务的传播行为配置不当可能导致事务失效。例如,如果设置了 Propagation.NOT_SUPPORTED,事务将不会生效。

  6. 异常类型不匹配
    默认情况下,Spring 仅在遇到未检查异常(继承自 RuntimeException)或错误(继承自 Error)时才会回滚事务。检查异常(继承自 Exception)不会触发回滚,除非明确配置。

    @Transactional(rollbackFor = Exception.class)
    
  7. 事务上下文丢失
    如果事务方法在新线程中执行(例如通过 @Async),事务上下文将丢失。

  8. 数据库不支持事务
    并非所有数据库都支持事务。如果使用的数据库不支持事务,@Transactional 将无效。

  9. 平台事务管理器配置不当
    如果平台事务管理器配置不当(例如,数据源未正确配置),事务也不会生效。

以下是一个综合示例,展示了如何正确配置 @Transactional

@Service
public class MyService {

    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    @Transactional(rollbackFor = Exception.class)
    public void transactionalMethod() {
        // 事务逻辑
        myRepository.save(new MyEntity());
        // 如果发生异常,事务将回滚
    }

    public void nonTransactionalMethod() {
        transactionalMethod();  // 事务不会生效
    }
}

通过理解和避免上述场景,可以确保 @Transactional 注解在 Spring 应用程序中正确地管理事务。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值