@Transactional 与多数据源@DS冲突问题

当在方法上添加了@Transactional注解后,Spring会通过AOP创建事务,使用默认数据源。如果需要操作多个数据库,未指定@DS的数据源会导致后续SQL仍使用同一数据源。解决办法是将不同库的操作分离成独立方法,并分别添加@DS和@Transactional(Propagation.REQUIRES_NEW)注解,以确保新事务启动并切换数据源。

@Transactional

方法添加了 @Transactional 注解,Spring 事务就会生效。此时,Spring TransactionInterceptor 会通过 AOP 拦截该方法,创建事务。而创建事务,势必就会获得数据源。那么 TransactionInterceptor 会使用 Spring DataSourceTransactionManager 创建事务,并将事务信息通过 ThreadLocal 绑定在当前线程。 因为@Transactional会创建事务然后获得数据源,因为我们service方法上没有@DS注解,就拿了默认数据源,并且在这之后,这个事务信息会通过threadLocal跟当前线程绑定,事务信息包括connection连接,也就意味着,在进入这个service方法的时候,当前事务就绑定了数据源,执行到下一个sql 时,因为connection已经存在,所以拿到的还是之前的数据源,这个时候就找不到另外库中的表了。

解决方法:

把不同库的操作方法分离成独立的方法,并都加上@Transactional和@DS注解(在service上加)。

注意: 一定要把@Transactional设置为Propagation.REQUIRES_NEW,这样在调用另一个事务方法时,TransactionInterceptor 会将原事务挂起,暂时性的将原事务信息和当前线程解绑。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值