(附源码gitHub下载地址)spring boot -jta-atomikos分布式事务
Posted qq1141100952com
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(附源码gitHub下载地址)spring boot -jta-atomikos分布式事务相关的知识,希望对你有一定的参考价值。
应用场景:双数据源,就是某些项目会涉及到两个数据源或者两个以上的数据源,这个多数据源的项目一般是数据同步,也就是把数据从另一个系统中,保存到另一个系统,两边的 数据库又不一样,比如一个mysql、一个Sql Server。但是不管是什么类型的数据库,我们都不管,直接连接就是。
为什么要使用分布式事务:顾名思义,事务就是回滚,比如如果一个在保存数据的时候,在A数据库已经 保存,但是在保存数据在B的过程抛出异常,那么是不是应该全部回滚,把已经 保存了的A、B数据库的数据全部回滚?答案是确定的。下面就解说:
pom.xml主要依赖:
<dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
properties配置文件:
#数据源一
spring.datasource.primary.url=jdbc:mysql://localhost:3306/test spring.datasource.primary.username=root spring.datasource.primary.password=root spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver spring.datasource.primary.xa-data-source-class-name=com.alibaba.druid.pool.xa.DruidXADataSource
#数据源二 spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test1 spring.datasource.secondary.username=root spring.datasource.secondary.password=root spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver spring.datasource.secondary.xa-data-source-class-name=com.alibaba.druid.pool.xa.DruidXADataSource
数据源的配置类:DataSourceConfig.class
import com.alibaba.druid.pool.xa.DruidXADataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @Configuration public class DataSourceConfig //这里一定要加主数据源的注解 @Primary @Bean(name = "primaryProperty") @ConfigurationProperties(prefix = "spring.datasource.primary") public DruidXADataSource primaryDataSource() return new DruidXADataSource();
//这里是第二个数据源 @Bean(name = "secondaryProperty") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DruidXADataSource secondaryDataSource() return new DruidXADataSource();
再分别配置他们的数据源:以便包扫描、事务交给jta-atomikos统一管理
主数据源配置类:
import com.alibaba.druid.pool.xa.DruidXADataSource; import com.atomikos.jdbc.AtomikosDataSourceBean; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; 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 javax.sql.DataSource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import tk.mybatis.spring.annotation.MapperScan; @Configuration @MapperScan(basePackages = "com.example.dao.primary", sqlSessionTemplateRef = "primarySqlSessionTemplate") public class PrimaryDBConfig @Bean(name = "primaryDataSource") public DataSource dataSourceCar(@Qualifier("primaryProperty") DruidXADataSource druidXADataSource) AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(druidXADataSource); xaDataSource.setUniqueResourceName("primaryDataSource"); return xaDataSource; @Bean(name = "primarySqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/primary/*Mapper.xml"));//扫描指定目录的xml return bean.getObject(); @Bean(name = "primarySqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate( @Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception return new SqlSessionTemplate(sqlSessionFactory);
同理,第二个数据源的配置SecondaryDBConfig.java
@Configuration @MapperScan(basePackages = "com.example.dao.secondary", sqlSessionTemplateRef = "secondarySqlSessionTemplate") public class SecondaryDBConfig @Bean(name = "secondaryDataSource") public DataSource dataSourceCar(@Qualifier("secondaryProperty") DruidXADataSource druidXADataSource) AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(druidXADataSource); xaDataSource.setUniqueResourceName("secondaryDataSource"); return xaDataSource; @Bean(name = "secondarySqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/secondary/*Mapper.xml"));//扫描指定目录的xml return bean.getObject(); @Bean(name = "secondarySqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate( @Qualifier("secondarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception return new SqlSessionTemplate(sqlSessionFactory);
最后我们还需要配置事务管理的配置类:TransactionManagerConfig.java,以便把数据源一,数据源二全部交给jta-atomikos管理,实现分布式事务管理:
import com.atomikos.icatch.jta.UserTransactionImp; import com.atomikos.icatch.jta.UserTransactionManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.jta.JtaTransactionManager; import javax.transaction.TransactionManager; import javax.transaction.UserTransaction; @Configuration public class TransactionManagerConfig @Bean(name = "userTransaction") public UserTransaction userTransaction() throws Throwable UserTransactionImp userTransactionImp = new UserTransactionImp(); userTransactionImp.setTransactionTimeout(10000); return userTransactionImp; @Bean(name = "atomikosTransactionManager") 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 return new JtaTransactionManager(userTransaction(),atomikosTransactionManager());
最后我们在service类上加上注解:@Transactional(value = "transactionManager", rollbackFor = Exception.class)
当value = "transactionManager",则是分布式事务的管理。至此,全部完成。
gitHub完整项目下载地址:https://gitee.com/qhThomas/springboot-mybatis-duria.git
以上是关于(附源码gitHub下载地址)spring boot -jta-atomikos分布式事务的主要内容,如果未能解决你的问题,请参考以下文章
高并发 WEB 服务器 nginx 源码通读中文分析注释,带详细函数注释及函数调用注释,附 github 地址,后期持续维护更新