Spring 多数据源事务管理,JPA为例

1.问题发现

在之前的项目中,一直都是单数据源项目,只要在yaml配置文件中,配置好了数据库信息,即可使用Spring的@Transactional注解触发事务。

但这次接手的项目需要用到两个数据源,除了需要在yaml配置文件中,做好数据库信息配置以外,还需要在代码层做一个配置config的配置,给不同的数据源做一个事务管理器,才能触发事务。

2.实战

2.1配置

application.yaml:

yaml 复制代码
spring:
  datasource:
    csdbg1:
      driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
      jdbc-url: jdbc:sqlserver://localhost:1433; DatabaseName=csdbg1;encrypt=false;useUnicode=true;characterEncoding=utf-8?rewriteBatchedStatements=true
      username: admin
      password: 123456
    csdbg7:
      driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
      jdbc-url: jdbc:sqlserver://localhost:1433; DatabaseName=csdbg7;encrypt=false;useUnicode=true;characterEncoding=utf-8?rewriteBatchedStatements=true
      username: admin
      password: 123456

config:
@EnableJpaRepositoriesbasePackages 是DAO层的包位置,不同的数据源,需要创建不同的包。
EntityManagerFactoryBuilderpackages设置实体类包的位置,不同的数据源,需要创建不同的包。

数据源1的config

java 复制代码
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "org.rx.gosc.mapper.gosc.g1", entityManagerFactoryRef = "csdbG1EntityManagerFactory", transactionManagerRef = "csdbG1TransactionManager")
public class CSDBG1JpaConfig {
   
   @Resource
   private JpaProperties jpaProperties;
   
   @Primary
   @Bean(name = "csdbG1DataSource")
   @ConfigurationProperties(prefix = "spring.datasource.csdbg1")
   public DataSource dataSource() {
      return DataSourceBuilder.create().build();
   }
   
   @Primary
   @Bean(name = "csdbG1EntityManagerFactory")
   public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder, @Qualifier("csdbG1DataSource") DataSource dataSource) {
      return builder
            // 设置数据源
            .dataSource(dataSource)
            // 设置jpa配置
            .properties(jpaProperties.getProperties())
            // 设置实体包名
            .packages("org.rx.gosc.pojo.entity.gosc.g1")
            // 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
            .persistenceUnit("csdbg1").build();
   }
   
   @Primary
   @Bean(name = "csdbG1EntityManager")
   public EntityManager entityManager(@Qualifier("csdbG1EntityManagerFactory") EntityManagerFactory factory) {
      return factory.createEntityManager();
   }
   
   @Primary
   @Bean(name = "csdbG1TransactionManager")
   public PlatformTransactionManager customerTransactionManager(@Qualifier("csdbG1EntityManagerFactory") EntityManagerFactory csdbrEntityManagerFactory) {
      return new JpaTransactionManager(csdbrEntityManagerFactory);
   }
   
   @Primary
   @Bean(name = "csdbG1JdbcTemplate")
   public JdbcTemplate csdbJdbcTemplate(@Qualifier("csdbG1DataSource") DataSource dataSource) {
      return new JdbcTemplate(dataSource);
   }
   
   @Bean(name = "csdbG1TransactionTemplate")
   @Primary
   public TransactionTemplate primaryTransactionTemplate(@Qualifier("csdbG1TransactionManager") PlatformTransactionManager transactionManager) {
      // 创建主数据源的 TransactionTemplate,绑定主事务管理器
      TransactionTemplate template = new TransactionTemplate(transactionManager);
      // 可选:设置事务传播行为、隔离级别等
      template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
      template.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
      return template;
   }
}

数据源2的config

java 复制代码
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "org.rx.gosc.mapper.gosc.g7", entityManagerFactoryRef = "csdbG7EntityManagerFactory", transactionManagerRef = "csdbG7TransactionManager")
public class CSDBG7JpaConfig {
   
   @Resource
   private JpaProperties jpaProperties;
   
   @Bean(name = "csdbG7DataSource")
   @ConfigurationProperties(prefix = "spring.datasource.csdbg7")
   public DataSource dataSource() {
      return DataSourceBuilder.create().build();
   }
   
   @Bean(name = "csdbG7EntityManagerFactory")
   public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder, @Qualifier("csdbG7DataSource") DataSource dataSource) {
      return builder
            // 设置数据源
            .dataSource(dataSource)
            // 设置jpa配置
            .properties(jpaProperties.getProperties())
            // 设置实体包名
            .packages("org.rx.gosc.pojo.entity.gosc.g7")
            // 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
            .persistenceUnit("csdbg7").build();
   }
   
   @Bean(name = "csdbG7EntityManager")
   public EntityManager entityManager(@Qualifier("csdbG7EntityManagerFactory") EntityManagerFactory factory) {
      return factory.createEntityManager();
   }
   
   @Bean(name = "csdbG7TransactionManager")
   public PlatformTransactionManager customerTransactionManager(@Qualifier("csdbG7EntityManagerFactory") EntityManagerFactory csdbrEntityManagerFactory) {
      return new JpaTransactionManager(csdbrEntityManagerFactory);
   }
   
   @Bean(name = "csdbG7JdbcTemplate")
   public JdbcTemplate csdbg7JdbcTemplate(@Qualifier("csdbG7DataSource") DataSource dataSource) {
      return new JdbcTemplate(dataSource);
   }
   
   @Bean(name = "csdbG7TransactionTemplate")
   @Primary
   public TransactionTemplate primaryTransactionTemplate(@Qualifier("csdbG7TransactionManager") PlatformTransactionManager transactionManager) {
      // 创建主数据源的 TransactionTemplate,绑定主事务管理器
      TransactionTemplate template = new TransactionTemplate(transactionManager);
      // 可选:设置事务传播行为、隔离级别等
      template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
      template.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
      return template;
   }
}

2.2使用

@Transactional注解中,添加事务管理器,即可使Service触发回滚,事务管理器是刚刚在config中已配置好了,如:@Transactional(transactionManager = "csdbG1TransactionManager")

相关推荐
填满你的记忆2 小时前
【从零开始——Redis 进化日志|Day5】分布式锁演进史:从 SETNX 到 Redisson 的完美蜕变
java·数据库·redis·分布式·缓存
nsjqj2 小时前
JavaEE初阶:多线程初阶(2)
java·开发语言
玩转数据库管理工具FOR DBLENS2 小时前
人工智能:演进脉络、核心原理与未来之路 审核中
数据库·人工智能·测试工具·数据库开发·数据库架构
晓风残月淡2 小时前
高性能MYSQL(四):查询性能优化
数据库·mysql·性能优化
cab52 小时前
MyBatis如何处理数据库中的JSON字段
数据库·json·mybatis
黎雁·泠崖2 小时前
Java面向对象:对象数组核心+综合实战
java·开发语言
天若有情6732 小时前
用MySQL+BI工具搭建企业级数据可视化看板:从数据准备到动态展示全攻略
数据库·mysql·信息可视化
Mr.LJie2 小时前
记录使用iText7合并PDF文件、PDF发票、PDF火车票
java·pdf
野生技术架构师2 小时前
2026最新最全Java 面试题大全(整理版)2000+ 面试题附答案详解
java·开发语言