springboot+jta+atomikos分布式多数据源事务管理 (SQLserver)

在我上一篇博客的项目基础上做更改

springboot多数据源分包式实现

首先我们来试一下没有更改的情况下

@Service
public class User2Service {

	@Autowired
	private User2Mapper mapper2;
	
	@Autowired
	private User2Mapper mapper1;
	
	@Transactional
	public void insert() {
		mapper1.insert();
		int a = 1/0;
		mapper2.insert();
	}

}
@Repository
public interface User1Mapper{

	@Insert("insert into user_demo values('事务管理','1')")
	public void insert();
}
@Repository
public interface User2Mapper {

	@Insert("insert into user_demo values('事务管理','2')")
	public void insert();
}

在User2Service中同时对User1Mapper 和User2Mapper进行事务管理,在中间的除零异常出现后,数据还是被保存到了数据库,但是只是UserMapper2的数据被保存到了数据库,UserMapper1的数据被回滚,这种情况下默认是只对@Primary的数据源进行事务管理

那我们就把事务管理交给atomikos

首先application.properties配置文件重新写一下,依赖引入一下

sqlserver.datasource.test1.url=jdbc:sqlserver://localhost:1433;DatabaseName=Test
sqlserver.datasource.test1.username=sa
sqlserver.datasource.test1.password=vhukze
 
sqlserver.datasource.test1.minPoolSize=3
sqlserver.datasource.test1.maxPoolSize=25
sqlserver.datasource.test1.maxLifetime=20000
sqlserver.datasource.test1.borrowConnectionTimeout=30
sqlserver.datasource.test1.loginTimeout=30
sqlserver.datasource.test1.maintenanceInterval=60
sqlserver.datasource.test1.maxIdleTime=60
sqlserver.datasource.test1.testQuery=select 1
#mybatis  配置文件
#sqlserver.datasource.test1.mapper-locations=classpath:mapper1/*.xml
#mybatis 对应的实体类
#sqlserver.datasource.test1.type-aliases-package=com.wangye.spbootjtaautomatic.model1
 
 
#sqlserver2
sqlserver.datasource.test2.url=jdbc:sqlserver://localhost:1433;DatabaseName=Test1
sqlserver.datasource.test2.username=sa
sqlserver.datasource.test2.password=vhukze
 
sqlserver.datasource.test2.minPoolSize=3
sqlserver.datasource.test2.maxPoolSize=25
sqlserver.datasource.test2.maxLifetime=20000
sqlserver.datasource.test2.borrowConnectionTimeout=30
sqlserver.datasource.test2.loginTimeout=30
sqlserver.datasource.test2.maintenanceInterval=60
sqlserver.datasource.test2.maxIdleTime=60
sqlserver.datasource.test2.testQuery=select 1
#mybatis  配置文件
#sqlserver.datasource.test2.mapper-locations=classpath:mapper2/*.xml
#mybatis 对应的实体类
#sqlserver.datasource.test2.type-aliases-package=com.wangye.spbootjtaautomatic.model2
扫描二维码关注公众号,回复: 9078776 查看本文章
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>

我这里没有建实体类也没有用配置文件 。

然后把之前的数据源配置类注释了 删了也行 我这里就注释了。

新建两个配置类


package com.vhukze.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.microsoft.sqlserver.jdbc.SQLServerXADataSource;
import com.vhukze.config.DBConfig1;

/**
* @author zsz
* @version 
* @创建时间:2019年9月3日 上午9:31:28
*/
@Configuration
@MapperScan(basePackages="com.vhukze.test1",sqlSessionTemplateRef="test1SqlSessionTemplate")
public class TestMybatisConfig1 {

	@Primary
	@Bean(name="test1DataSource")
	public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
		SQLServerXADataSource sqlServerXADataSource = new SQLServerXADataSource();
		sqlServerXADataSource.setURL(testConfig.getUrl());
		sqlServerXADataSource.setUser(testConfig.getUsername());
		sqlServerXADataSource.setPassword(testConfig.getPassword());
		
		AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
		atomikosDataSourceBean.setXaDataSource(sqlServerXADataSource);
		atomikosDataSourceBean.setUniqueResourceName("test1DataSource");
		
		atomikosDataSourceBean.setMinPoolSize(testConfig.getMinPoolSize());
		atomikosDataSourceBean.setMaxPoolSize(testConfig.getMaxPoolSize());
		atomikosDataSourceBean.setMaxLifetime(testConfig.getMaxLifeTime());
		atomikosDataSourceBean.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeOut());
		atomikosDataSourceBean.setLoginTimeout(testConfig.getLoginTimeOut());
		atomikosDataSourceBean.setMaintenanceInterval(testConfig.getMaintenanceInterval());
		atomikosDataSourceBean.setMaxIdleTime(testConfig.getMaxIdleTime());
		atomikosDataSourceBean.setTestQuery(testConfig.getTestQuery());
		
		return atomikosDataSourceBean;
	}
	
	@Bean(name="test1SqlSessionFactory")
	public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception { 
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		
		return bean.getObject();
	}
	
	@Bean(name="test1SqlSessionTemplate")
	public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) { 
		return new SqlSessionTemplate(sqlSessionFactory);
	}
}


第二个就把这里面的test1和DBConfig1改成test2和DBConfig2 就好了,跟之前的配置类差不多,就是把DataSource交给atomikos管理了

然后创建一下里面需要用到的配置实体类DBConfig1和DBConfig2 在新建的一个config包下


package com.vhukze.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
* @author zsz
* @version 
* @创建时间:2019年9月3日 上午9:55:23
*/
@ConfigurationProperties(prefix="sqlserver.datasource.test1")
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;
	get set 方法
	
}


这个跟上面一样    DBConfig2 就把注解里面的test1改成test2

在启动类添加扫描config包 还有一个什么开启配置文件 就把两个字节码文件给它就行

@SpringBootApplication
@ComponentScan(basePackages= {"com.vhukze.config","com.vhukze.controller","com.vhukze.test1.service","com.vhukze.test2.service","com.vhukze.datasource"})
@MapperScan({"com.vhukze.test1.mapper","com.vhukze.test2.mapper"})
@EnableConfigurationProperties(value = {DBConfig1.class,DBConfig2.class})
public class App {
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}

到这里就改完了配置,也没多麻烦。

启动项目访问映射路径------报错……

无法创建 XA 控制连接。错误:“找不到存储过程 'master..xp_sqljdbc_xa_init_ex'

这是因为sql server库的服务器没有配置XA事务和安装JDBC插件

解决步骤写在了另一篇博客中-->无法创建XA控制连接

而且我之前用的是公司服务器中的SQLserver,然后换成本机的了,但是不知道连接密码,解决办法

-->SQLserver改登录密码

都弄好之后测试成功,可以同时管理两个数据源的事务

发布了66 篇原创文章 · 获赞 35 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_41890624/article/details/100508833