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

相关推荐
NE_STOP17 分钟前
MyBatis-mybatis入门与增删改查
java
孟陬4 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
想用offer打牌4 小时前
一站式了解四种限流算法
java·后端·go
华仔啊4 小时前
Java 开发千万别给布尔变量加 is 前缀!很容易背锅
java
也些宝5 小时前
Java单例模式:饿汉、懒汉、DCL三种实现及最佳实践
java
Nyarlathotep01135 小时前
SpringBoot Starter的用法以及原理
java·spring boot
wuwen55 小时前
WebFlux + Lettuce Reactive 中 SkyWalking 链路上下文丢失的修复实践
java
SimonKing6 小时前
GitHub 10万星的OpenCode,正在悄悄改变我们的工作流
java·后端·程序员
Seven977 小时前
虚拟线程深度解析:轻量并发编程的未来趋势
java