Java 事务失效场景全解析

在 Java 开发中,事务管理是保证数据一致性的核心机制,尤其是在 Spring 框架中,@Transactional注解的使用极大简化了事务配置。然而,在实际开发中,事务常常会因为一些细节问题而失效,导致数据异常。本文将详细解析 Java 事务失效的八大场景,每个场景都提供代码示例与对应的修复方案。

一、事务方法非 public 修饰

失效原理

Spring 的@Transactional注解默认只对public方法生效。这是因为 Spring AOP 在实现事务管理时,无论是 JDK 动态代理还是 CGLIB 代理,都无法对非 public 方法(private、protected、默认访问权限)进行有效的事务增强。

失效代码

java运行

@Service
public class UserService {
    // 非public方法,事务注解失效
    @Transactional
    void updateUser(Long id) { 
        userMapper.updateStatus(id, 1);
    }
}

修复方案

将事务方法修改为public访问权限。

修复后代码

java运行

@Service
public class UserService {
    // 修改为public方法,事务生效
    @Transactional
    public void updateUser(Long id) { 
        userMapper.updateStatus(id, 1);
    }
}

二、异常被捕获且未重新抛出

失效原理

Spring 事务默认仅在遇到未捕获的RuntimeExceptionError时触发回滚。如果方法内部使用try-catch捕获了异常且未重新抛出,事务管理器会认为没有异常发生,从而不会执行回滚操作。

失效代码

java运行

@Service
public class OrderService {
    @Transactional
    public void createOrder(Order order) {
        try {
            orderMapper.insert(order);
            // 模拟异常
            int i = 1 / 0;
        } catch (Exception e) {
            // 捕获异常但未抛出,事务不会回滚
            log.error("创建订单失败", e);
        }
    }
}

修复方案

方案一:捕获异常后重新抛出
方案二:使用TransactionAspectSupport手动触发回滚

修复后代码(方案一)

java运行

@Service
public class OrderService {
    @Transactional
    public void createOrder(Order order) {
        try {
            orderMapper.insert(order);
            // 模拟异常
            int i = 1 / 0;
        } catch (Exception e) {
            log.error("创建订单失败", e);
            // 重新抛出异常,触发事务回滚
            throw new RuntimeException("创建订单失
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值