在我上一篇博客的项目基础上做更改
首先我们来试一下没有更改的情况下
@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
<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,然后换成本机的了,但是不知道连接密码,解决办法
都弄好之后测试成功,可以同时管理两个数据源的事务