在我上一篇博客的项目基础上做更改
首先我们来试一下没有更改的情况下
1.@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包 还有一个什么开启配置文件 就把两个字节码文件给它就行
1.@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改登录密码
都弄好之后测试成功,可以同时管理两个数据源的事务