目前使用的是 AbstractRoutingDataSource+AOP 动态切换数据源,现在有个需求要在一个请求中分别对 A 库和 B 库各新增一条数据。
伪代码如下:
public class FooController {
@PostMapping(value = "/foo")
public void foo() {
// AOP 会拦截这两个 service 中的方法,然后切换数据源
fooService.save(); // 在 A 库插入数据,这里是正常的
barService.save(); // 在 B 库插入数据,这里切换不了数据源,使用的还是 A 数据源
}
}
问题是只有第一个方法切换数据源有效,第二个方法切换不了数据源。
应该是第二个方法切换数据源之后,没有触发下面这段方法,想问下有没有其它解决方案?
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceHolder.getKey();
}
}
PS:orm 框架用的 jpa
1
nekolr Sep 22, 2022
建议贴一下 aop 的相关代码
|
2
wolfie Sep 22, 2022
注掉 fooService 看看,能不能走 AOP 。
|
3
Kaiv2 Sep 22, 2022
需求是什么?
|
4
joooooker21 Sep 22, 2022
DynamicDataSourceHolder.setKey( b )
|
5
sirierx Sep 22, 2022
baomidou.dynamic.datasource
|
6
7911364440 OP @wolfie 两个 service 都是可以被 aop 拦截的
|
7
wolfie Sep 22, 2022
贴部分代码吧。
在看看有没有涉及到 异步 相关的东西。 |
8
cheng6563 Sep 22, 2022
第二个方法必须要启动新事物,不然事务管理器会保持连接
|
9
so2back Sep 22, 2022
需要切换数据源的方法用 @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)注解试试,也就是按楼上说的,需要起一个新的事务
|
10
7911364440 OP |
11
MrZYB Sep 22, 2022
切换数据源写个 setDataSource 方法,在调用第 2 个 service.save()时手动切换数据源。
|
12
git00ll Sep 22, 2022
AbstractPlatformTransactionManager 类上有一个 setTransactionSynchronization 方法,可以控制不是真实事物情况下,是否需要使用事务管理器进行连接同步。
可选值为 SYNCHRONIZATION_ALWAYS ,SYNCHRONIZATION_ON_ACTUAL_TRANSACTION ,SYNCHRONIZATION_NEVER 三个字段。 你这里的情况,把事务管理器上的 setTransactionSynchronization 设为 SYNCHRONIZATION_ON_ACTUAL_TRANSACTION ,试试看 |
13
czn6mx Sep 22, 2022
AOP after 清掉 ThreadLocal dataSourceKey
|
14
cslive Sep 23, 2022
jpa 不需要 aop 切换,需要单独设置每个数据源针对的实体类所在的位置
|
15
Aresxue Oct 8, 2022 生产级代码就别自己写了,用 https://github.com/baomidou/dynamic-datasource-spring-boot-starter 这个好了,唯一要注意的是分布式事务的部分需要自己重写一下,如果是为了学习也可以看一下人家的代码,也是 AbstractRoutingDataSource 这个路子
|