事务相关问题

目录

1.在一个bean中,一个无事务的方法调用有事务的方法,事务失效

2.在一个事务中进行数据源的切换不生效

3.一个有事务的方法调用另一个有事务的方法,如果在第二个方法中出现异常,事务回滚,然后在第一个方法中,没有判断第二个方法的返回值,直接进行事务的提交,这时会报错,因为事务已经回滚了,不能进行提交


1.在一个bean中,一个无事务的方法调用有事务的方法,事务失效

原因是在一个类中调用,使用this调用,this指的是当前原始对象的实例,而非代理对象

解决方法:将要添加事务的方法写在其他bean中,方法上添加事务,然后注入进行进行调用

@Service
public class UserService {
    public void methodA() {
        // 无事务方法
        this.methodB();  // 直接调用,事务失效
    }
    
    @Transactional
    public void methodB() {
        // 有事务方法
        // 事务失效原因:this指向原始对象,而不是代理对象
        // 解决方案:通过注入的代理对象调用
    }
}

// 正确写法
@Service
public class UserService {
    @Autowired
    private UserService self;  // 注入代理对象
    
    public void methodA() {
        self.methodB();  // 通过代理对象调用,事务生效
    }
    
    @Transactional
    public void methodB() {
        // 有事务方法
    }
}

2.在一个事务中进行数据源的切换不生效

因为开启事务后是不能进行动态数据源的切换的

事务内是不支持进行数据源的切换的,一旦开启事务,这个事务只能对应一个数据源

解决方法:规划好方法的逻辑,不在事务内进行数据源的切换

@Service
public class UserService {
    @Autowired
    private DataSource dataSource;
    
    @Transactional
    public void method() {
        // 开启事务
        try {
            // 业务操作1
            
            // 尝试切换数据源
            DynamicDataSourceContextHolder.setDataSource("slave");
            // 此时切换数据源不会生效,因为事务已经开启
            // 事务会继续使用原来的数据源
            
            // 业务操作2
        } finally {
            DynamicDataSourceContextHolder.clear();
        }
    }
}

// 正确写法:在事务方法之前切换数据源
@Service
public class UserService {
    @Autowired
    private UserService self;
    
    public void method() {
        // 先切换数据源
        DynamicDataSourceContextHolder.setDataSource("slave");
        try {
            // 再开启事务
            self.transactionalMethod();
        } finally {
            DynamicDataSourceContextHolder.clear();
        }
    }
    
    @Transactional
    public void transactionalMethod() {
        // 事务方法
    }
}

3.一个有事务的方法调用另一个有事务的方法,如果在第二个方法中出现异常,事务回滚,然后在第一个方法中,没有判断第二个方法的返回值,直接进行事务的提交,这时会报错,因为事务已经回滚了,不能进行提交

解决方法:可以在第二个方法中开启一个新事物,这样两个事务互补干扰

也可以在第二个方法中不添加事务,直接使用方法一的事务,如果方法二异常,则在方法一中进行判断,进行事务的操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值