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")

相关推荐
符哥20085 小时前
C++ 进阶知识点整理
java·开发语言·jvm
静听山水5 小时前
StarRocks表模型详解
数据库
静听山水6 小时前
Redis核心数据结构-Set
数据结构·数据库·redis
Sayuanni%36 小时前
初阶_多线程1(线程含义与关键属性)
java
程序媛徐师姐6 小时前
Java基于微信小程序的模拟考试系统,附源码+文档说明
java·微信小程序·java模拟考试系统小程序·模拟考试微信小程序·模拟考试系统小程序·模拟考试小程序·java模拟考试小程序
疯狂敲代码的老刘6 小时前
JDK 1.6到25 全版本网盘合集 (Windows + Mac + Linux)
java·linux·windows·macos·jdk
夕除6 小时前
js--15
java·jvm·spring
数研小生6 小时前
亚马逊商品列表API详解
前端·数据库·python·pandas
洛豳枭薰6 小时前
MySQL 并行复制
数据库·mysql
无尽的沉默6 小时前
Redis下载安装
数据库·redis·缓存