【Spring事物三千问】Spring配置多数据源 vs 给多个数据源添加事物管理

在Spring中配置多数据源主要涉及定义多个DataSource和SqlSessionFactory。如果不需要事务管理,配置相对简单。但若需事务管理,则需为每个数据源添加TransactionManager,并启用@EnableTransactionManagement以拦截@Transactional方法。
摘要由CSDN通过智能技术生成

在 Spring 中配置多数据源 与 给多个数据源添加事物管理是有区别的。
如果只需要使用到多个数据源,而不需要进行事物管理,是可以进行简单处理的。

Spring 中配置多数据源

如果不需要对数据源进行事物管理的话,在 Spring 中配置多个数据源是相对比较容易的。
根据前面分析 多事务管理器&多数据源的处理,我们知道,如果使用 MyBatis 来操作 DB 的话,那么配置多数据源只需要两步:
1、定义 n 个数据源 DataSource
2、定义基于 DataSource 的 SqlSessionFactory (通过 MyBatis 操作 sql)

多数据源的配置示例如下:

// Master 数据源配置
@Configuration
@MapperScan(basePackages = "com.kvn.mapper.master", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterMybatisConfig {

    @Bean("master")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    @Bean("masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("master") DataSource dataSource) throws Exception {
        // 设置数据源
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        // mapper 的xml文件位置
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String locationPattern = "classpath*:/mapper/master/*.xml";
        mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        // 对应数据库的 entity 位置
        String typeAliasesPackage = "com.kvn.entity.master";
        mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        return mybatisSqlSessionFactoryBean.getObject();
    }
}

------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------

// Slave 数据源配置
@Configuration
@MapperScan(basePackages = "com.kvn.mapper.slave", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class SlaveMybatisConfig {

    @Bean("slave")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    @Bean("slaveSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("slave") DataSource dataSource) throws Exception {
        // 设置数据源
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        // mapper 的xml文件位置
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String locationPattern = "classpath*:/mapper/master/*.xml";
        mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        // 对应数据库的 entity 位置
        String typeAliasesPackage = "com.kvn.entity.slave";
        mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        return mybatisSqlSessionFactoryBean.getObject();
    }

}

Spring 中配置多数据源的事物管理

如果要给数据源添加添加事物管理的功能的话,那么就需要在多数据源配置的基础之上,再给每个 DataSource 添加事物管理器(TransactionManager),同时,开启对 @Transactional 方法的拦截。
所以,配置多数据源的事物管理的步骤如下:
1、定义 n 个数据源 DataSource
2、定义基于 DataSource 的 SqlSessionFactory (通过 MyBatis 操作 sql)
3、定义基于 DataSource 的 TransactionManager(事物管理器)
4、通过 @EnableTransactionManagement 来开启对 @Transactional 方法的拦截

多数据源的事物管理配置示例如下:

// Master 数据源配置
@Configuration
@MapperScan(basePackages = "com.kvn.mapper.master", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterMybatisConfig {

    @Bean("master")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 创建 master 数据源的事物管理器
     */
    @Bean(name = "masterTxManager")
    public PlatformTransactionManager masterTxManager(@Qualifier("master") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    
    @Bean("masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("master") DataSource dataSource) throws Exception {
        // 设置数据源
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        // mapper 的xml文件位置
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String locationPattern = "classpath*:/mapper/master/*.xml";
        mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        // 对应数据库的 entity 位置
        String typeAliasesPackage = "com.kvn.entity.master";
        mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        return mybatisSqlSessionFactoryBean.getObject();
    }
}


------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------


// Slave 数据源配置
@Configuration
@MapperScan(basePackages = "com.kvn.mapper.slave", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class SlaveMybatisConfig {

    @Bean("slave")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 创建 slave 数据源的事物管理器
     */
    @Bean(name = "slaveTxManager")
    public PlatformTransactionManager slaveTxManager(@Qualifier("slave") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    
    @Bean("slaveSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("slave") DataSource dataSource) throws Exception {
        // 设置数据源
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        // mapper 的xml文件位置
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String locationPattern = "classpath*:/mapper/master/*.xml";
        mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        // 对应数据库的 entity 位置
        String typeAliasesPackage = "com.kvn.entity.slave";
        mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        return mybatisSqlSessionFactoryBean.getObject();
    }
}

小结

抽象出来看的话,在 Spring 中配置多数据源,其实就是定义多个 DataSource 的 bean。
而配置多数据源的事物管理,就是在多个 DataSource bean 的基础之上,再为每个 DataSource 添加 TransactionManager 事物管理器。

附:
PlatformTransactionManager 是 Spring 事务实现的核心接口。它提供了三个方法用来管理事务:
1、 getTransaction(TransactionDefinition)
2、 commit(TransactionStatus)
3、 rollback(TransactionStatus)

PlatformTransactionManager 提供了管理事物的能力,而对 @Transactional 事物方法拦截的处理是通过 @EnableTransactionManagement 来开启的。
@EnableTransactionManagement 的作用是自动注册 BeanFactoryTransactionAttributeSourceAdvisor,让 TransactionInterceptor 来拦截 @Transactional 标记的方法。

所以,PlatformTransactionManager@EnableTransactionManagement 的共同作用下,让 Spring 拥有了对 @Transactional 标记的方法进行事物管理的能力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老王学源码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值