SpringBoot使用dynamic配置多数据源时使用@Transactional事务在非primary的数据源上遇到的问题

情景

  • Springboot项目中使用dynamic配置了多个数据源;
  • primary(主要)数据源是oracle;
  • 其他数据源有postgres;
  • 想要在非primary数据源中使用@Transactional进行事务管理;
  • 在这之前没有单独配置Transactional事务的bean。

出现的问题

  • 非primary数据源中事务的sql检查报错

原因

使用primary数据源的数据库(oracle)方言去检查非primary数据源的数据库(Postgresql)的sql语句,出现sql语法不兼容的情况;

解决方法:

如果使用了springboot dynamic 多数据源配置时,primary数据源和其他数据原的数据库类型不一致,但是还想要在非primary数据源中使用@Transactional事务

  • 使用自定义的transactionManager

    java 复制代码
    @Configuration
    public class TransactionManagerConfig {
    
        @Autowired
        private DataSource dataSource; // 动态数据源
    
        @Bean("db1TransactionManager")
        public DataSourceTransactionManager jiaoyiTransactionManager() {
            DynamicRoutingDataSource dynamicDataSource = (DynamicRoutingDataSource) dataSource;
            DataSource jiaoyiDataSource = dynamicDataSource.getDataSource("db1");
            return new DataSourceTransactionManager(jiaoyiDataSource);
        }
    
        @Bean("db2TransactionManager")
        public DataSourceTransactionManager clearingTransactionManager() {
            DynamicRoutingDataSource dynamicDataSource = (DynamicRoutingDataSource) dataSource;
            DataSource clearingDataSource = dynamicDataSource.getDataSource("db2");
            return new DataSourceTransactionManager(clearingDataSource);
        }
    }
  • 在服务中使用

    java 复制代码
    @Service
    public class MultiDataSourceService {
    
        @Autowired
        private Db1Mapper db1Mapper;
    
        @Autowired
        private Db2Mapper db2Mapper;
    
        // 使用db1数据源的事务
        @Transactional("db1TransactionManager")
        public void processJiaoyi() {
            db1Mapper.insertData();
        }
    
        // 使用db2数据源的事务
        @Transactional("db2TransactionManager")
        public void processClearing() {
            db2Mapper.updateData();
        }
    }

注意事项

  • 数据源切换与事务顺序: 确保@DS注解与@Transactional在同一方法或调用链中,避免数据源切换与事务管理器不匹配。
相关推荐
Goboy11 分钟前
夯爆了,我被一个一句话接入的免费可观测平台策反了,那一刻我决定放弃用了3年的Prometheus
后端·docker·kubernetes
奶油话梅糖1 小时前
打开项目 0.9 秒、内存只有 IDEA 的 1/12:OpenIDEA 用 Rust 把 IntelliJ IDEA 重造了一遍
java·rust·github·intellij-idea
回家路上绕了弯1 小时前
Agent in the Sandbox:当 AI 有了自己的开发环境
后端
vipxieliang1 小时前
语言对比卡:PHP vs Go vs Java 的优缺点、适用场景与「为什么选 PHP」
java·go·php
陈随易1 小时前
TanStarter,从搭建到支付,一步到位开始赚美元
前端·后端·程序员
Rain的Java大神之路1 小时前
公交App上“还有2站,约5分钟”怎么实现?90%的人答错这道大厂面试题:GPS漂移、ETA不准、10万QPS热点读全拆透(附完整代码)
java·后端·面试
挖掘狂人1 小时前
MySQL 深分页优化:limit 100000, 10 慢在哪,怎么救
后端·sql·mysql
golang学习记1 小时前
IDEA 2026.3 远程开发迎来重磅升级
java·ide·intellij-idea·远程开发
天天被压力2 小时前
【A股分钟级高频数据完全手册 #04】指数分钟级行情数据接口:沪深指数Pro版最新分时取数
java·人工智能·python
敲代码的小小酥2 小时前
谈SpringMVC与Spring WebFlux的区别与适用场景
java·后端·spring