问题描述
jkms项目用到了多数据源。
一个导入接口,需要先查询mysql获取经销商列表,然后查询pgsql获取激活记录,执行一波校验,最后将excel表格解析出来的数据插入到mysql中。
因为有插入,所以要带事务注解回滚。
在同一个数据下,Mapper的@DS注解失效,导致用mysql的驱动去执行pgsql,出现报错
问题原因
- 在开启事务的同时,会从数据库连接池获取数据库连接,一个事务绑定一个连接,一旦绑定后,在整个事务的过程中,使用的数据库连接conn都是同一个。
- Spring中@Transactional是通过APO+ThreadLocal实现的,再被拦截方法主体执行前会通过getConnection获取数据库连接conn保存到ThreadLocal中,然后在执行被拦截的事务方法中对数据进行CRUD时,会再次从 ThradLocal 获取之前创建的connection
如果某个方法没有使用@DS注解标识使用的数据源,会使用默认的数据源 - @DS注解添加在mapper接口上无效
解决方案
- 既然事务开启后无法切换数据源, 那么可以在事务开启前就切换好数据源
- 一个事务只能关联一个数据源,那么可以开启2个事务,关联不同的的数据库
- @DS加在mapper接口上无效,可直接加在方法上
将查询pg库的方法单独抽离,修改事务传播属性,添加@DS("pgsql")即可
@Transactional(propagation = Propagation.REQUIRES_NEW)
@DS("postgres")
public List<String> getDeviceTraceMacList(List<String> deviceMacList){
List<DeviceTrace> deviceTraceList = this.list(new LambdaQueryWrapper<DeviceTrace>().in(DeviceTrace::getDeviceMac, deviceMacList));
List<String> macList = deviceTraceList.stream().map(DeviceTrace::getDeviceMac).toList();
return macList;
}
6 条评论
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
作者的观点新颖且实用,让人在阅读中获得了新的思考和灵感。
网络流行语融入自然,贴近年轻读者。
技术前瞻性分析体现行业敏感度。
警惕陷入二元对立思维,可尝试中间路径。