springboot多数据源事务

Sabthever

Springboot编写业务过程中经常要做数据源的切换,但是事务本身是按照单个数据库为单位去做事务管理的,就需要有屏蔽他们不同性的一个应用级的事务管理。

具体业务场景是在一个方法中,有如下报错:

1
2
org.springframework.jdbc.UncategorizedSQLException: 
### Error querying database. Cause: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block springboot 事务

我报错的地方是一个mysql数据源的mapper接口,但是报错却是报的psql错误,但是我看显示的切换也切换成功了,但是实际上会发现里面的Transactional管理出现了问题。

我到若依gitee官方论坛上找相应的问题,找到了这样一个讨论:

https://gitee.com/y_project/RuoYi/issues/I3R7AH#note_8239683

里面就讲到需要用Atomikos来增强@Transactional功能,使之能够管理多数据源,做一个应用层的管理。若依的文档上也有相应的描述:

https://doc.ruoyi.vip/ruoyi/document/cjjc.html#%E9%9B%86%E6%88%90atomikos%E5%AE%9E%E7%8E%B0%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1

我们只要在framework模块的pom.xml添加atomikos依赖就能解决这个问题。

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>

好了,问题解决了,拜拜!!

However!

我后来又发现出问题了,具体调用长这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Override
@Transactional(rollbackFor = Exception.class)
public void scheduleManually() {
updatePermissionArea();
updatePermissionUnit();
}

@Scheduled(cron = "0 0 0 * * ?")
@Transactional(rollbackFor = Exception.class)
public void updatePermissionArea() {
List<String> areaList = permissionListMapper.getPermissionArea();
String areaStr = JSON.toJSONString(areaList);
log.info("updatePermissionArea areaStr: {}", areaStr);
int result = permissionListMapper.updatePermissionArea(areaStr);
log.info("updatePermissionArea num: {}", result);
}

@Scheduled(cron = "0 0 0 * * ?")
@Transactional(rollbackFor = Exception.class)
public void updatePermissionUnit() {
List<String> unitList = permissionListMapper.getPermissionUnit();
String unitStr = JSON.toJSONString(unitList);
log.info("updatePermissionUnit unitStr: {}", unitStr);
int result = permissionListMapper.updatePermissionUnit(unitStr);
log.info("updatePermissionUnit num: {}", result);
}

我有两个定时任务要执行,这些都要做数据源的切换,然后还留了一个手动执行的接口,在service层直接调用两个方法,我寻思着上面加上@Transactional应该没问题的,毕竟我单个方法都屏蔽了。

关键就是出问题了,我在scheduleManually()上加了注解它就是出问题了,但是把这个注解去掉,下面两个注解还在就不会出问题,也就是说在这边@Transactional无法做一个套用,所以要是确实

另外:

在我使用idea多开程序时会有一个报错:

1
Log already in use? tmlog in D:\projectFile\idea\dmd-java-cockpit-share-compass\transaction-logs\

这是引入atomikos执行后,在相应的事务日志文件中会加上锁,所以想多开的话可以在vm-option中加入如下改变新的事务日志。

1
-Dspring.jta.atomikos.properties.log-base-dir=D:/项目路径/service1-tmlogs/

然后就能启动了,关于多开的内容可以看idea多开程序

  • 标题: springboot多数据源事务
  • 作者: Sabthever
  • 创建于 : 2025-09-09 14:35:36
  • 更新于 : 2025-09-10 13:59:01
  • 链接: https://sabthever.cn/2025/09/09/technology/java/springboot多数据源事务/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
目录
springboot多数据源事务