多个数据源存在着事务管理问题,事务只影响自己的数据源,
解决方案:使用 springboot + jta+ atomikos 分布式事务管理
步骤:
- 1.添加jta事务依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency>
- 2.修改数据库连接配置数据 application.properties
3.添加2个配置模型 com.zjc.dbconfig/ DBConfig1 DBConfig2(相同,修改配置名称即可)# Mysql 数据源1 mysql.datasource.sbtest1.url = jdbc:mysql://localhost:3306/sbtest1?useUnicode=true&characterEncoding=utf-8 mysql.datasource.sbtest1.username = root mysql.datasource.sbtest1.password = root mysql.datasource.sbtest1.minPoolSize = 3 mysql.datasource.sbtest1.maxPoolSize = 25 mysql.datasource.sbtest1.maxLifetime = 20000 mysql.datasource.sbtest1.borrowConnectionTimeout = 30 mysql.datasource.sbtest1.loginTimeout = 30 mysql.datasource.sbtest1.maintenanceInterval = 60 mysql.datasource.sbtest1.maxIdleTime = 60 mysql.datasource.sbtest1.testQuery = select 1 # Mysql 2 数据源2 mysql.datasource.sbtest2.url =jdbc:mysql://localhost:3306/sbtest2?useUnicode=true&characterEncoding=utf-8 mysql.datasource.sbtest2.username =root mysql.datasource.sbtest2.password =root mysql.datasource.sbtest2.minPoolSize = 3 mysql.datasource.sbtest2.maxPoolSize = 25 mysql.datasource.sbtest2.maxLifetime = 20000 mysql.datasource.sbtest2.borrowConnectionTimeout = 30 mysql.datasource.sbtest2.loginTimeout = 30 mysql.datasource.sbtest2.maintenanceInterval = 60 mysql.datasource.sbtest2.maxIdleTime = 60 mysql.datasource.sbtest2.testQuery = select 1
@ConfigurationProperties("mysql.datasource.sbtest1") public class DBConfig1 { private String url; private String username; private String password; private int minPoolSize; private int maxPoolSize; private int maxLifetime; private int borrowConnectionTimeout; private int loginTimeout; private int maintenanceInterval; private int maxIdleTime; private String testQuery; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getMinPoolSize() { return minPoolSize; } public void setMinPoolSize(int minPoolSize) { this.minPoolSize = minPoolSize; } public int getMaxPoolSize() { return maxPoolSize; } public void setMaxPoolSize(int maxPoolSize) { this.maxPoolSize = maxPoolSize; } public int getMaxLifetime() { return maxLifetime; } public void setMaxLifetime(int maxLifetime) { this.maxLifetime = maxLifetime; } public int getBorrowConnectionTimeout() { return borrowConnectionTimeout; } public void setBorrowConnectionTimeout(int borrowConnectionTimeout) { this.borrowConnectionTimeout = borrowConnectionTimeout; } public int getLoginTimeout() { return loginTimeout; } public void setLoginTimeout(int loginTimeout) { this.loginTimeout = loginTimeout; } public int getMaintenanceInterval() { return maintenanceInterval; } public void setMaintenanceInterval(int maintenanceInterval) { this.maintenanceInterval = maintenanceInterval; } public int getMaxIdleTime() { return maxIdleTime; } public void setMaxIdleTime(int maxIdleTime) { this.maxIdleTime = maxIdleTime; } public String getTestQuery() { return testQuery; } public void setTestQuery(String testQuery) { this.testQuery = testQuery; }
- 4.重新配置两个数据源 datasource/ DataSource01 DataSource02
- DataSource02 去掉@Priamry==主数据源,对应扫描包com.zjc.sbtest2.mapper
-
@Configuration//注解到springboot容器中 @MapperScan(basePackages="com.zjc.sbtest1.mapper",sqlSessionFactoryRef="sbtest1SqlSessionFactory") public class DataSource01 { // 配置数据源 @Primary //主数据源 @Bean(name = "sbtest1DataSource") public DataSource testDataSource(DBConfig1 testConfig) throws SQLException { MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource(); mysqlXaDataSource.setUrl(testConfig.getUrl()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); mysqlXaDataSource.setPassword(testConfig.getPassword()); mysqlXaDataSource.setUser(testConfig.getUsername()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(mysqlXaDataSource); xaDataSource.setUniqueResourceName("sbtest1DataSource"); xaDataSource.setMinPoolSize(testConfig.getMinPoolSize()); xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize()); xaDataSource.setMaxLifetime(testConfig.getMaxLifetime()); xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout()); xaDataSource.setLoginTimeout(testConfig.getLoginTimeout()); xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval()); xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime()); xaDataSource.setTestQuery(testConfig.getTestQuery()); return xaDataSource; } @Bean(name = "sbtest1SqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("sbtest1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Bean(name = "sbtest1SqlSessionTemplate") public SqlSessionTemplate testSqlSessionTemplate( @Qualifier("sbtest1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
- 5.App.class配置扫描路径
@EnableAutoConfiguration @ComponentScan(basePackages = {"com.zjc"}) @EnableConfigurationProperties(value = {DBConfig1.class, DBConfig2.class}) public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }