springboot jta atomikos实现分布式事物管理
这篇文章主要介绍了springbootjtaatomikos实现分布式事物管理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
当项目在连接多个数据库时可能会发生事务问题,即一个库的事务不可能去操作另一个数据库的事务,这时就需要使用atomikos对数据库的事务进行统一的管理
第一步添加atomikos的依赖
org.springframework.boot spring-boot-starter-jta-atomikos
第二步配置数据源,我这里有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:SELECT1FROMDUAL 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:SELECT1FROMDUAL test-while-idle:true logging: level: org.springframework.web:debug
然后创建DBConfig1和DBConfig2,这两个实体类就是存放两个数据源的数据的。
packagecom.cgb.config;
importorg.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix="spring.datasource.system")
publicclassDBConfig1{
privateStringjdbc-url;
privateStringusername;
privateStringpassword;
privateintminPoolSize;
privateintmaxPoolSize;
privateintmaxLifetime;
privateintborrowConnectionTimeout;
privateintloginTimeout;
privateintmaintenanceInterval;
privateintmaxIdleTime;
privateStringtestQuery;
publicStringgetJdbc-url(){
returnurl;
}
publicvoidsetJdbc-url(Stringjdbc-url){
this.jdbc-url=jdbc-url;
}
publicStringgetUsername(){
returnusername;
}
publicvoidsetUsername(Stringusername){
this.username=username;
}
publicStringgetPassword(){
returnpassword;
}
publicvoidsetPassword(Stringpassword){
this.password=password;
}
publicintgetMinPoolSize(){
returnminPoolSize;
}
publicvoidsetMinPoolSize(intminPoolSize){
this.minPoolSize=minPoolSize;
}
publicintgetMaxPoolSize(){
returnmaxPoolSize;
}
publicvoidsetMaxPoolSize(intmaxPoolSize){
this.maxPoolSize=maxPoolSize;
}
publicintgetMaxLifetime(){
returnmaxLifetime;
}
publicvoidsetMaxLifetime(intmaxLifetime){
this.maxLifetime=maxLifetime;
}
publicintgetBorrowConnectionTimeout(){
returnborrowConnectionTimeout;
}
publicvoidsetBorrowConnectionTimeout(intborrowConnectionTimeout){
this.borrowConnectionTimeout=borrowConnectionTimeout;
}
publicintgetLoginTimeout(){
returnloginTimeout;
}
publicvoidsetLoginTimeout(intloginTimeout){
this.loginTimeout=loginTimeout;
}
publicintgetMaintenanceInterval(){
returnmaintenanceInterval;
}
publicvoidsetMaintenanceInterval(intmaintenanceInterval){
this.maintenanceInterval=maintenanceInterval;
}
publicintgetMaxIdleTime(){
returnmaxIdleTime;
}
publicvoidsetMaxIdleTime(intmaxIdleTime){
this.maxIdleTime=maxIdleTime;
}
publicStringgetTestQuery(){
returntestQuery;
}
publicvoidsetTestQuery(StringtestQuery){
this.testQuery=testQuery;
}
}
然后创建两个数据源RuanMyBatisConfig和YouMyBatisConfig,注意@Primary注解只能有一个。
packagecom.cgb.datasource;
importjava.sql.SQLException;
importjavax.sql.DataSource;
importorg.apache.ibatis.session.SqlSessionFactory;
importorg.mybatis.spring.SqlSessionFactoryBean;
importorg.mybatis.spring.SqlSessionTemplate;
importorg.mybatis.spring.annotation.MapperScan;
importorg.springframework.beans.factory.annotation.Qualifier;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.context.annotation.Primary;
importcom.atomikos.jdbc.AtomikosDataSourceBean;
importcom.cgb.config.DBConfig1;
importcom.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
@Configuration
@MapperScan(basePackages="com.cgb.ruan",sqlSessionTemplateRef="testSqlSessionTemplate")
publicclassRuanMyBatisConfig{
//配置数据源
@Primary
@Bean(name="dataSource1")
publicDataSourcetestDataSource(DBConfig1testConfig)throwsSQLException{
MysqlXADataSourcemysqlXaDataSource=newMysqlXADataSource();
mysqlXaDataSource.setUrl(testConfig.getUrl());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
mysqlXaDataSource.setPassword(testConfig.getPassword());
mysqlXaDataSource.setUser(testConfig.getUsername());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
AtomikosDataSourceBeanxaDataSource=newAtomikosDataSourceBean();
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());
returnxaDataSource;
}
@Bean(name="testSqlSessionFactory")
publicSqlSessionFactorytestSqlSessionFactory(@Qualifier("dataSource1")DataSourcedataSource)
throwsException{
SqlSessionFactoryBeanbean=newSqlSessionFactoryBean();
bean.setDataSource(dataSource);
returnbean.getObject();
}
@Bean(name="testSqlSessionTemplate")
publicSqlSessionTemplatetestSqlSessionTemplate(
@Qualifier("testSqlSessionFactory")SqlSessionFactorysqlSessionFactory)throwsException{
returnnewSqlSessionTemplate(sqlSessionFactory);
}
}
其实在多个数据源的时候,我们怎么去指定数据库呢?
其中一个做法是写注解,表明使用哪个数据库,但是这种是不是很麻烦。最好的做法是分包管理:
好啦,大功告成,我们来看看效果吧。
我们发现控制台打印添加学生成功,好我们看看数据库里有没有数据呢?
毫无疑问是没有的,说明事务起作用了。那我们把那行异常代码注释掉,再看看效果。成功了,去看看数据库有没有呢。
ojbk,想想同时操作多个数据库,是不是很爽啊,哈哈哈。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。