多数据源的配置和事务

背景:

最近做了一个需求,是从 A 系统导入会员资料到 B 系统,
由于项目中做了数据源的切换,在 debug 的时候发现数据没回滚,这里简单记录一下,后续再补充。

代码


    @Autowired
    private  DataSourceTransactionManager aTransactionManager;

    @Autowired
    private  DataSourceTransactionManager bTransactionManager;
    
    public void copyData() {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        // A 系统开启事务
        TransactionStatus statusA = aTransactionManager.getTransaction(def);
        
        // 在A数据源中的操作
        // ...

		// B 系统开启事务
        TransactionStatus statusB = bTransactionManager.getTransaction(def);

        // 在B数据源中的操作
        // ...
        
        if (/*操作失败*/) {
            aTransactionManager.rollback(statusA);
            bTransactionManager.rollback(statusB);
        } else {
            aTransactionManager.commit(statusA);
            bTransactionManager.commit(statusB);
        }
    }

顺便这里简单记录下多数据源在 SpringBoot 中的配置:

# yml 配置多数据源
server:
  port: 9999
spring:
  application:
    name:data-synchronizer
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://xxx/db_name?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&autoReconnect=true&useSSL=false&failOverReadOnly=false&allowPublicKeyRetrieval=true
    username: root
    password: xxx
    hikari:
      pool-name: target-db
      connection-timeout: 10000
      validation-timeout: 10000
      register-mbeans: true

data-source:
  database:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: oracle.jdbc.OracleDriver
    jdbc-url: jdbc:oracle:thin:@xxx:1521:orcl
    username: xxx
    password: xxx
    hikari:
      pool-name: source-db
      connection-timeout: 10000
      validation-timeout: 10000
      
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  typeAliasesPackage: com.xxxx.entity
  configuration:
    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
    map-underscore-to-camel-case: false
    cache-enabled: true

两个数据源配置类

/**
 * 源数据库
 * @author xxx
 * @date 2023/11/23
 */
@Configuration
public class SourceDatabaseConfig {

    @Bean(name = "sourceDataSource")
    @ConfigurationProperties(prefix = "data-source.database")
    public DataSource sourceDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public JdbcTemplate sourceJdbcTemplate() {
        return new JdbcTemplate(sourceDataSource());
    }
}


/**
 * 目标数据库
 * @author xxx
 * @date 2023/11/23
 */
@Configuration
@MapperScan(basePackages = "mapper", sqlSessionTemplateRef = "sqlSessionTemplate")
public class TargetDatabaseConfig {

    @Bean
    @Primary
    public DataSource dataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().build();
    }

    @Bean(name = "sqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));

        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisConfiguration.setMapUnderscoreToCamelCase(false);
        mybatisConfiguration.setLogImpl(Slf4jImpl.class);
        mybatisConfiguration.setCacheEnabled(true);
        sqlSessionFactoryBean.setConfiguration(mybatisConfiguration);

        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setBanner(false);
        sqlSessionFactoryBean.setGlobalConfig(globalConfig);
        return sqlSessionFactoryBean.getObject();
    }

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

    @Bean(name = "sqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值