(十二)Spring Boot+Druid+Mybatis实现JTA分布式事务
来源:互联网 发布:梯形螺纹加工编程 编辑:程序博客网 时间:2024/04/27 12:50
源码下载:点此下载 整合Mybatis 配置两个SqlSessionFactory 分别扫描不同的包
对于分布式事务而言, JTA 是一个不错的解决方案,通常 JTA 需要应用服务器的支持,但在查阅 SpringBoot 的文档时发现,它推荐了 Atomikos 和 Bitronix 两种无需服务器支持的分布式事务组件,在这两个组件中, Atomikos 更受大家的好评,所以我选择使用它.
对于分布式事务而言, JTA 是一个不错的解决方案,通常 JTA 需要应用服务器的支持,但在查阅 SpringBoot 的文档时发现,它推荐了 Atomikos 和 Bitronix 两种无需服务器支持的分布式事务组件,在这两个组件中, Atomikos 更受大家的好评,所以我选择使用它.
引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jta-atomikos</artifactId></dependency>
application.properties
#配置jdbc数据源#配置多数据源#数据源名称(与下列配置的数据源对应,多个数据源要配多个名称)jdbc.datasources=ds,ds1jdbc.ds.driverClassName=com.mysql.jdbc.Driverjdbc.ds.url=jdbc\:mysql\://localhost\:3306/ryx?characterEncoding\=UTF-8&pinGlobalTxToPhysicalConnection\=truejdbc.ds.username=rootjdbc.ds.password=123456jdbc.ds1.driverClassName=com.mysql.jdbc.Driverjdbc.ds1.url=jdbc\:mysql\://172.20.1.5\:3306/ryx?characterEncoding\=UTF-8&pinGlobalTxToPhysicalConnection\=truejdbc.ds1.username=rootjdbc.ds1.password=root#druid监控平台账号密码druid.username=rootdruid.password=Ruyixing2017注意:使用Druid配置JTA事务需要使用DruidXADataSource,不要再使用DruidDataSource了
TestMyBatisConfig.java
package com.test.springboot.config.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.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import com.alibaba.druid.pool.DruidDataSource;import com.alibaba.druid.pool.xa.DruidXADataSource;import com.atomikos.jdbc.AtomikosDataSourceBean;import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;@Configuration// basePackages 最好分开配置 如果放在同一个文件夹可能会报错@MapperScan(basePackages = "com.test.springboot.dao", sqlSessionTemplateRef = "testSqlSessionTemplate")public class TestMyBatisConfig {@Value("${jdbc.ds.driverClassName}")private String driver;@Value("${jdbc.ds.url}")private String url;@Value("${jdbc.ds.username}")private String username;@Value("${jdbc.ds.password}")private String password;// 配置数据源@Primary@Bean(name = "testDataSource",initMethod="init",destroyMethod="close")public DataSource dataSource() throws SQLException{DruidXADataSource dataSource=new DruidXADataSource();//DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username); dataSource.setPassword(password); //配置最大连接 dataSource.setMaxActive(300); //配置初始连接 dataSource.setInitialSize(20); //配置最小连接 dataSource.setMinIdle(10); //连接等待超时时间 dataSource.setMaxWait(60000); //间隔多久进行检测,关闭空闲连接 dataSource.setTimeBetweenEvictionRunsMillis(60000); //一个连接最小生存时间 dataSource.setMinEvictableIdleTimeMillis(300000); //连接等待超时时间 单位为毫秒 缺省启用公平锁, //并发效率会有所下降, 如果需要可以通过配置useUnfairLock属性为true使用非公平锁 dataSource.setUseUnfairLock(true); //用来检测是否有效的sql dataSource.setValidationQuery("select 'x'"); dataSource.setTestWhileIdle(true); //申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能 dataSource.setTestOnBorrow(false); //归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能 dataSource.setTestOnReturn(false); //打开PSCache,并指定每个连接的PSCache大小启用poolPreparedStatements后, //PreparedStatements 和CallableStatements 都会被缓存起来复用, //即相同逻辑的SQL可以复用一个游标,这样可以减少创建游标的数量。 dataSource.setPoolPreparedStatements(true); dataSource.setMaxOpenPreparedStatements(20); //配置sql监控的filter dataSource.setFilters("stat,wall,log4j"); try { dataSource.init(); } catch (SQLException e) { e.printStackTrace(); } AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(dataSource);xaDataSource.setUniqueResourceName("testDataSource");/*xaDataSource.setMinPoolSize(10);xaDataSource.setMaxPoolSize(300);xaDataSource.setMaxLifetime(20000);xaDataSource.setBorrowConnectionTimeout(30);xaDataSource.setLoginTimeout(30);xaDataSource.setMaintenanceInterval(60);xaDataSource.setMaxIdleTime(60);xaDataSource.setTestQuery("select 'x'");*/ return xaDataSource;}@Bean(name = "testSqlSessionFactory")public SqlSessionFactory testSqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource)throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dataSource);//bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/test/springboot/dao/*.xml"));return bean.getObject();}@Bean(name = "testSqlSessionTemplate")public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {return new SqlSessionTemplate(sqlSessionFactory);}}
Test2MyBatisConfig.java
package com.test.springboot.config.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.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import com.alibaba.druid.pool.DruidDataSource;import com.alibaba.druid.pool.xa.DruidXADataSource;import com.atomikos.jdbc.AtomikosDataSourceBean;import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;@Configuration@MapperScan(basePackages = "com.test.springboot.dao2", sqlSessionTemplateRef = "test2SqlSessionTemplate")public class Test2MyBatisConfig {@Value("${jdbc.ds1.driverClassName}")private String driver;@Value("${jdbc.ds1.url}")private String url;@Value("${jdbc.ds1.username}")private String username;@Value("${jdbc.ds1.password}")private String password;@Bean(name = "test2DataSource",initMethod="init",destroyMethod="close")public DataSource dataSource() throws SQLException{DruidXADataSource dataSource=new DruidXADataSource();//DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username); dataSource.setPassword(password); //配置最大连接 dataSource.setMaxActive(300); //配置初始连接 dataSource.setInitialSize(20); //配置最小连接 dataSource.setMinIdle(10); //连接等待超时时间 dataSource.setMaxWait(60000); //间隔多久进行检测,关闭空闲连接 dataSource.setTimeBetweenEvictionRunsMillis(60000); //一个连接最小生存时间 dataSource.setMinEvictableIdleTimeMillis(300000); //连接等待超时时间 单位为毫秒 缺省启用公平锁, //并发效率会有所下降, 如果需要可以通过配置useUnfairLock属性为true使用非公平锁 dataSource.setUseUnfairLock(true); //用来检测是否有效的sql dataSource.setValidationQuery("select 'x'"); dataSource.setTestWhileIdle(true); //申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能 dataSource.setTestOnBorrow(false); //归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能 dataSource.setTestOnReturn(false); //打开PSCache,并指定每个连接的PSCache大小启用poolPreparedStatements后, //PreparedStatements 和CallableStatements 都会被缓存起来复用, //即相同逻辑的SQL可以复用一个游标,这样可以减少创建游标的数量。 dataSource.setPoolPreparedStatements(true); dataSource.setMaxOpenPreparedStatements(20); //配置sql监控的filter dataSource.setFilters("stat,wall,log4j"); try { dataSource.init(); } catch (SQLException e) { e.printStackTrace(); } AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(dataSource);xaDataSource.setUniqueResourceName("test2DataSource");/*xaDataSource.setMinPoolSize(10);xaDataSource.setMaxPoolSize(300);xaDataSource.setMaxLifetime(20000);xaDataSource.setBorrowConnectionTimeout(30);xaDataSource.setLoginTimeout(30);xaDataSource.setMaintenanceInterval(60);xaDataSource.setMaxIdleTime(60);xaDataSource.setTestQuery("select 'x'");*/ return xaDataSource;}@Bean(name = "test2SqlSessionFactory")public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dataSource);//bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/test/springboot/dao2/*.xml"));return bean.getObject();}@Bean(name = "test2SqlSessionTemplate")public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {return new SqlSessionTemplate(sqlSessionFactory);}}
然后要配置JTA事务管理
TransactionManagerConfig.java
package com.test.springboot.config.datasource;import javax.transaction.TransactionManager;import javax.transaction.UserTransaction;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.DependsOn;import org.springframework.transaction.PlatformTransactionManager;import org.springframework.transaction.annotation.EnableTransactionManagement;import org.springframework.transaction.jta.JtaTransactionManager;import com.atomikos.icatch.jta.UserTransactionImp;import com.atomikos.icatch.jta.UserTransactionManager;@Configuration@ComponentScan@EnableTransactionManagementpublic class TransactionManagerConfig {@Bean(name = "userTransaction")public UserTransaction userTransaction() throws Throwable {UserTransactionImp userTransactionImp = new UserTransactionImp();userTransactionImp.setTransactionTimeout(10000);return userTransactionImp;}@Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")public TransactionManager atomikosTransactionManager() throws Throwable {UserTransactionManager userTransactionManager = new UserTransactionManager();userTransactionManager.setForceShutdown(false);return userTransactionManager;}@Bean(name = "transactionManager")@DependsOn({ "userTransaction", "atomikosTransactionManager" })public PlatformTransactionManager transactionManager() throws Throwable {UserTransaction userTransaction = userTransaction();JtaTransactionManager manager = new JtaTransactionManager(userTransaction,atomikosTransactionManager());return manager;}}
测试方法
在需要事务的service方法内注入两个数据库的操作对应的mapper,然后在方法上标注@Transactional注解就可以了,跟之前使用方法没什么两样
@Override@Transactionalpublic Integer insetStudent(Student student) {Integer integer = studentMapper.insetStudent(student);Integer integer2 = studentMapper2.insetStudent(student);int a=10/0;return integer;}
阅读全文
1 0
- (十二)Spring Boot+Druid+Mybatis实现JTA分布式事务
- Spring+JTA实现分布式事务
- 分布式事务操作之Spring+JTA+mybatis
- 分布式事务操作之Spring+JTA+mybatis
- Spring-boot + atomikos + druid分布式事务配置
- Spring JTA 分布式事务
- Spring JTA 分布式事务
- spring+mybatis+atomikos 实现JTA事务
- Spring Boot Druid 多数据源 Atomikos 分布式事务
- spring boot + jta + druid整合demo
- Spring多数据源分布式事务管理/springmvc+spring+atomikos[jta]+druid+mybatis
- Spring多数据源分布式事务管理/springmvc+spring+atomikos[jta]+druid+mybatis
- Spring多数据源分布式事务管理/springmvc+spring+atomikos[jta]+druid+mybatis
- Spring分布式事务- 三种实现方式(Spring+JTA)
- Spring分布式事务- 三种实现方式(Spring+JTA)
- Spring实现分布式事务JTA(使用atomiko实现)
- Spring实现分布式事务JTA(使用atomiko实现)
- Postgresql 分布式事务JTA实现Atomikos与Spring集成实践
- java小白学习日记
- DJango-如何快速准备Python虚拟开发环境并快速定制一个项目
- 五章通信笔记·电磁场与电磁波
- vim编辑器配置文件
- 百度编辑器相关修改
- (十二)Spring Boot+Druid+Mybatis实现JTA分布式事务
- clion下调试caffe出现提示cannot find -lopencv_dep_cudart
- 合成/聚合复用原则
- Hibernate09_映射关系---OneToMany双向
- 【优化】Problem 800: 可怜的火鸡
- Terraform 使用
- Bitmap的高效加载
- 【读书笔记】大话设计模式 第二章 策略模式
- tomcat:输入localhost能访问后台,IP不能访问