这篇文章主要介绍了springboot jta atomikos实现分布式事物管理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
当项目在连接多个数据库时可能会发生事务问题,即一个库的事务不可能去操作另一个数据库的事务,这时就需要使用atomikos对数据库的事务进行统一的管理
第一步添加atomikos的依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jta-atomikos</artifactId>
- </dependency>
第二步配置数据源,我这里有2个数据库(ruan和youxianqi),你有多少就加多少。
- spring:
- datasource:
- system:
- jdbc-url: jdbc:oracle:thin:@localhost:1521/orcl
- driver-class-name: oracle.jdbc.OracleDriver
- username: yuan
- password: 1234
- initial-size: 5
- min-idle: 5
- max-active: 20
- min-evictable-idle-time-millis: 300000
- validation-query: SELECT 1 FROM DUAL
- test-while-idle: true
- kllogt:
- jdbc-url: jdbc:oracle:thin:@localhost:1521/orcl
- driver-class-name: oracle.jdbc.OracleDriver
- username: youxianqi
- password: youxianqi
- initial-size: 5
- min-idle: 5
- max-active: 20
- min-evictable-idle-time-millis: 300000
- validation-query: SELECT 1 FROM DUAL
- test-while-idle: true
- logging:
- level:
- org.springframework.web: debug
然后创建DBConfig1和DBConfig2,这两个实体类就是存放两个数据源的数据的。
- package com.cgb.config;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- @ConfigurationProperties(prefix = "spring.datasource.system")
- public class DBConfig1 {
- private String jdbc-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 getJdbc-url() {
- return url;
- }
- public void setJdbc-url(String jdbc-url) {
- this.jdbc-url= jdbc-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;
- }
- }
然后创建两个数据源RuanMyBatisConfig和YouMyBatisConfig,注意@Primary注解只能有一个。
- package com.cgb.datasource;
- import java.sql.sqlException;
- import javax.sql.DataSource;
- import org.apache.ibatis.session.sqlSessionFactory;
- import org.mybatis.spring.sqlSessionfactorybean;
- import org.mybatis.spring.sqlSessionTemplate;
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Primary;
- import com.atomikos.jdbc.AtomikosDataSourceBean;
- import com.cgb.config.DBConfig1;
- import com.MysqL.jdbc.jdbc2.optional.MysqLXADataSource;
- @Configuration
- @MapperScan(basePackages = "com.cgb.ruan",sqlSessionTemplateRef = "testsqlSessionTemplate")
- public class RuanMyBatisConfig {
- // 配置数据源
- @Primary
- @Bean(name = "dataSource1")
- 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("dataSource1");
- 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 = "testsqlSessionFactory")
- public sqlSessionFactory testsqlSessionFactory(@Qualifier("dataSource1") DataSource dataSource)
- throws Exception {
- sqlSessionfactorybean bean = new sqlSessionfactorybean();
- bean.setDataSource(dataSource);
- return bean.getObject();
- }
- @Bean(name = "testsqlSessionTemplate")
- public sqlSessionTemplate testsqlSessionTemplate(
- @Qualifier("testsqlSessionFactory") sqlSessionFactory sqlSessionFactory) throws Exception {
- return new sqlSessionTemplate(sqlSessionFactory);
- }
- }
其实在多个数据源的时候,我们怎么去指定数据库呢?
其中一个做法是写注解,表明使用哪个数据库,但是这种是不是很麻烦。最好的做法是分包管理:
好啦,大功告成,我们来看看效果吧。
我们发现控制台打印添加学生成功,好我们看看数据库里有没有数据呢?
毫无疑问是没有的,说明事务起作用了。那我们把那行异常代码注释掉,再看看效果。成功了,去看看数据库有没有呢。
ojbk,想想同时操作多个数据库,是不是很爽啊,哈哈哈。