Bootstrap

在 Druid 配置多个数据源并给每个数据源配置单独的事务管理器

在 Druid 配置多个数据源并给每个数据源配置单独的事务管理器

在企业级应用中,可能会涉及到多个数据源的使用,尤其是在使用 Druid 作为数据库连接池时,配置多个数据源并为每个数据源配置独立的事务管理器变得尤为重要。下面是如何在 Spring Boot 中配置多个 Druid 数据源并为每个数据源配置单独的事务管理器的详细步骤。

1. 添加依赖

首先,你需要在 pom.xml 文件中添加 Druid 和 Spring 事务管理相关的依赖。

<dependencies>
    <!-- Druid 数据源依赖 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.2.8</version>
    </dependency>
    
    <!-- Spring Boot 数据源事务管理依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    
    <!-- Spring事务管理 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
    </dependency>
</dependencies>

2. 配置 Druid 数据源

接下来,需要在 application.ymlapplication.properties 文件中配置多个数据源。例如,假设我们有两个数据源:masterDataSourceslaveDataSource

application.yml 配置示例:

spring:
  datasource:
    # 主数据源配置
    druid:
      master:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/master_db
        username: root
        password: root_password
        initial-size: 5
        min-idle: 5
        max-active: 20
        max-wait: 60000
        validation-query: SELECT 1

    # 从数据源配置
    druid:
      slave:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/slave_db
        username: root
        password: root_password
        initial-size: 5
        min-idle: 5
        max-active: 20
        max-wait: 60000
        validation-query: SELECT 1

3. 配置多个数据源 Bean

在 Java 配置类中,你需要为每个数据源创建一个 Druid 的 DataSource Bean。

@Configuration
@EnableTransactionManagement
public class DataSourceConfig {

    // 配置主数据源
    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.master")
    public DataSource masterDataSource() {
        return new DruidDataSource();
    }

    // 配置从数据源
    @Bean(name = "slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.slave")
    public DataSource slaveDataSource() {
        return new DruidDataSource();
    }
}

4. 配置事务管理器

为了确保每个数据源的事务独立,我们需要为每个数据源配置一个事务管理器。使用 @Primary 注解确保一个事务管理器是默认的,并使用 @Qualifier 注解来显式指定其他事务管理器。

@Configuration
@EnableTransactionManagement
public class TransactionManagerConfig {

    // 配置主数据源的事务管理器
    @Primary
    @Bean(name = "masterTransactionManager")
    public PlatformTransactionManager masterTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    // 配置从数据源的事务管理器
    @Bean(name = "slaveTransactionManager")
    public PlatformTransactionManager slaveTransactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

5. 配置 @TransactionManager 注解

在实际开发中,你可能需要在特定的服务方法中使用事务。在这种情况下,可以使用 @Transactional 注解来指明使用哪个事务管理器。

@Service
public class MyService {

    @Autowired
    @Qualifier("masterTransactionManager")
    private PlatformTransactionManager transactionManager;

    @Transactional(transactionManager = "masterTransactionManager")
    public void performMasterTransaction() {
        // 执行主数据源相关的事务操作
    }

    @Transactional(transactionManager = "slaveTransactionManager")
    public void performSlaveTransaction() {
        // 执行从数据源相关的事务操作
    }
}

6. 使用 @EnableTransactionManagement 启用事务管理

在启动类类中使用 @EnableTransactionManagement 注解来启用 Spring 的事务管理支持。

@SpringBootApplication
@EnableTransactionManagement
public class AppApplication {

}

7. 使用 @Primary@Qualifier 解决冲突

如果你在配置多个事务管理器时遇到冲突,可以使用 @Primary 注解来指定一个默认的事务管理器,而在需要的地方使用 @Qualifier 注解来明确指定事务管理器。

@Primary
@Bean(name = "masterTransactionManager")
public PlatformTransactionManager masterTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

8. 总结

通过上面的步骤,你可以在 Spring Boot 项目中为每个 Druid 数据源配置独立的事务管理器。主要步骤包括:

  • 配置多个数据源。
  • 为每个数据源创建独立的事务管理器。
  • 使用 @Qualifier 注解在服务层指定使用哪一个事务管理器。

这种方式不仅能解决多个数据源的事务问题,还能在实际的开发中实现事务的隔离和更高效的事务管理。如果需要处理更加复杂的场景,例如使用多个数据库进行联动操作,可以考虑使用 ChainedTransactionManager 来组合多个事务管理器。

;