Closed edwardlzh closed 1 year ago
你这种相当于开启了两个事务,Spring事务中是不能切换数据源的,可以用多数据源提供的@DsTransactional
spring事务中不是可以依靠org.springframework.transaction.annotation.Transactional#transactionManager切换事务管理器吗?当然我意思是不使用@DS的情况下,通过注册多个数据源和配套的TransactionManager,然后在嵌套的service调用中切换事务管理器。 @ZPZP1
可以注册多个事务管理器,以DataSourceTransactionManager为例会判断你当前线程是否存在持有链接作为判断是否事务存在的依据,你要每个事务管理器自己实现是否存在事务的判断逻辑,和事务处理的具体逻辑,这是很难控制而且很容易有问题,如果你非要这样做,可以试试
实际上,我的意思是如果我不用@DS注解,伪代码:
@Transactional serviceA{
@Transactional(transactionManager = "firstTransactionManager")
serviceB.xx();
@Transactional(transactionManager = "secondTransactionManager")
serviceC.xx();
}
两个事务管理器分别对应两个数据源,这个代码,不会出现表不存在的问题,并且确实是一个事务控制了两个数据源连接。 同时,如果serviceB的传播机制为request_new,也是没有问题的。这种写法,虽然配置起来比较麻烦,比如配置多个事务管理器。但是不会像@DS那样与@Transactional冲突。而且,@DSTransactional虽然能解决@DS数据源切换的问题,但是我认为它舍弃了原生@Transactional的事务传播机制,好像也不太合适吧?
@ZPZP1
@edwardlzh 选择你认为对的方式去做
Please fill it out carefully, or it will be closed. 请认真填写,不然会直接关闭。
Enviroment
JDK Version(required): 1.8.0_131
SpringBoot Version(required): 2.7.12
dynamic-datasource-spring-boot-starter Version(required):3.5.2
druid Version(optional):
Describe what happened
Expected Result: 希望serviceB回滚,并且serviceB的@DS能生效
Actual Result: serviceB的@DS生效了,但是事务是独立的
Steps to reproduce
Step 1 serviceA调用serviceB,serviceA开启了事务,serviceB加了@ds注解,发现serviceB数据源切换失败,于是在serviceB上加了@transactional(propagation = Propagation.REQUIRES_NEW),数据源切换成功,但是发现事情没这么简单。
Step 2 这是伪代码 @transactional serviceA{
@ds("sla1") @transactional(propagation = Propagation.REQUIRES_NEW) serviceB.xx();
@transactional serviceC.xx(); }
请问,有什么好的解决办法吗?