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

相关推荐
沃尔威武7 小时前
数据库 Sinks(.net8)
数据库·.net·webview
014-code7 小时前
订单超时取消与库存回滚的完整实现(延迟任务 + 状态机)
java·开发语言
Dreamboat¿8 小时前
SQL 注入漏洞
数据库·sql
java1234_小锋8 小时前
Java高频面试题:Springboot的自动配置原理?
java·spring boot·面试
曹牧9 小时前
Oracle数据库中,将JSON字符串转换为多行数据
数据库·oracle·json
被摘下的星星9 小时前
MySQL count()函数的用法
数据库·mysql
末央&9 小时前
【天机论坛】项目环境搭建和数据库设计
java·数据库
徒 花9 小时前
数据库知识复习07
数据库·作业
xiaoye37089 小时前
Spring 中高级面试题
spring·面试
枫叶落雨2229 小时前
ShardingSphere 介绍
java