代码编织梦想

jta:Java Transaction API,即是java中对事务处理的api 即 api即是接口的意思

atomikos:Atomikos TransactionsEssentials 是一个为Java平台提供增值服务的并且开源类事务管理器

2、application.properties---->注意前缀

# Mysql 1
mysql.datasource.test1.url = jdbc:mysql://192.168.25.11:3306/18-08-12-manyDatasource1?useUnicode=true&characterEncoding=utf-8
mysql.datasource.test1.username = root
mysql.datasource.test1.password = @sS19980713
mysql.datasource.test1.minPoolSize = 3
mysql.datasource.test1.maxPoolSize = 25
mysql.datasource.test1.maxLifetime = 20000
mysql.datasource.test1.borrowConnectionTimeout = 30
mysql.datasource.test1.loginTimeout = 30
mysql.datasource.test1.maintenanceInterval = 60
mysql.datasource.test1.maxIdleTime = 60
 
# Mysql 2
mysql.datasource.test2.url =jdbc:mysql://192.168.25.11:3306/18-08-12-manyDatasource2?useUnicode=true&characterEncoding=utf-8
mysql.datasource.test2.username =root
mysql.datasource.test2.password =@sS19980713
mysql.datasource.test2.minPoolSize = 3
mysql.datasource.test2.maxPoolSize = 25
mysql.datasource.test2.maxLifetime = 20000
mysql.datasource.test2.borrowConnectionTimeout = 30
mysql.datasource.test2.loginTimeout = 30
mysql.datasource.test2.maintenanceInterval = 60
mysql.datasource.test2.maxIdleTime = 60

 3、书写读取配置类1和2

package czs.config;
 
import org.springframework.boot.context.properties.ConfigurationProperties;
 
import lombok.Data;
 
@Data
/**
 * 将application.properties配置文件中配置自动封装到实体类字段中
 * @author Administrator
 */
@ConfigurationProperties(prefix = "mysql.datasource.test1") // 注意这个前缀要和application.properties文件的前缀一样
public class DBConfig1 {
 
	private String url;
	// 比如这个url在properties中是这样子的mysql.datasource.test1.username = root
	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;
}

4、开启扫描注册上面的两个配置文件类

5、两个数据源管理Bean

package czs.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 com.atomikos.jdbc.AtomikosDataSourceBean;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
 
import czs.config.DBConfig1;
 
@Configuration
// basePackages 最好分开配置 如果放在同一个文件夹可能会报错
@MapperScan(basePackages = "czs.mapper1", sqlSessionTemplateRef = "testSqlSessionTemplate")
public class MyBatisConfig1 {
 
	// 配置数据源
	@Bean(name = "testDataSource")
	public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
		MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
		mysqlXaDataSource.setUrl(testConfig.getUrl());
		mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
		mysqlXaDataSource.setPassword(testConfig.getPassword());
		mysqlXaDataSource.setUser(testConfig.getUsername());
		mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
 
		// 将本地事务注册到创 Atomikos全局事务
		AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
		xaDataSource.setXaDataSource(mysqlXaDataSource);
		xaDataSource.setUniqueResourceName("testDataSource");
 
		xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
		xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
		xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
		xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
		xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
		xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
		xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
		xaDataSource.setTestQuery(testConfig.getTestQuery());
		return xaDataSource;
	}
 
	@Bean(name = "testSqlSessionFactory")
	public SqlSessionFactory testSqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource)
			throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		return bean.getObject();
	}
 
	@Bean(name = "testSqlSessionTemplate")
	public SqlSessionTemplate testSqlSessionTemplate(
			@Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
		return new SqlSessionTemplate(sqlSessionFactory);
	}
}
package czs.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 com.atomikos.jdbc.AtomikosDataSourceBean;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
 
import czs.config.DBConfig2;
 
@Configuration
@MapperScan(basePackages = "czs.mapper2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class MyBatisConfig2 {
 
	// 配置数据源
	@Bean(name = "test2DataSource")
	public DataSource testDataSource(DBConfig2 testConfig) throws SQLException {
		MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
		mysqlXaDataSource.setUrl(testConfig.getUrl());
		mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
		mysqlXaDataSource.setPassword(testConfig.getPassword());
		mysqlXaDataSource.setUser(testConfig.getUsername());
		mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
 
		AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
		xaDataSource.setXaDataSource(mysqlXaDataSource);
		xaDataSource.setUniqueResourceName("test2DataSource");
 
		xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
		xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
		xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
		xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
		xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
		xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
		xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
		xaDataSource.setTestQuery(testConfig.getTestQuery());
		return xaDataSource;
	}
 
	@Bean(name = "test2SqlSessionFactory")
	public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)
			throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		return bean.getObject();
	}
 
	@Bean(name = "test2SqlSessionTemplate")
	public SqlSessionTemplate testSqlSessionTemplate(
			@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
		return new SqlSessionTemplate(sqlSessionFactory);
	}
}

有两个不同的地方要注意

           1、@MapperScan(basePackages = "czs.mapper2", sqlSessionTemplateRef = "test2SqlSessionTemplate")

                          basePackages扫描的mapper类包不要扫错了

           2、testDataSource()的参数为第三步的DBConfig1和DBConfig2

 

6、Service

package czs.mapper1;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import czs.mapper2.UserMapper2;
 
/**
* @author czs
* @version 创建时间:2018年8月12日 下午7:28:07 
*/
@Service
public class ManyService1 {
 
	@Autowired
	private UserMapper1 userMapper1;
 
	@Autowired
	private UserMapper2 userMapper2;
 
	// 开启事务,由于使用jta+atomikos解决分布式事务,所以此处不必再指定事务
	@Transactional
	public int insert(String name, Integer age) {
		int insert = userMapper1.insert(name, age);
		int i = 1 / age;// 赋值age为0故意引发事务
		return insert;
	}
 
	// 开启事务,由于使用jta+atomikos解决分布式事务,所以此处不必再指定事务
	@Transactional
	public int insertDb1AndDb2(String name, Integer age) {
		int insert = userMapper1.insert(name, age);
		int insert2 = userMapper2.insert(name, age);
		int i = 1 / age;// 赋值age为0故意引发事务
		return insert + insert2;
	}
 
}

   7、Controller

 

	@RequestMapping(value = "insertDb1AndDb2")
	public int insertDb1AndDb2(String name, Integer age) {
		return manyService1.insertDb1AndDb2(name, age);
	}

8、测试------------访问:http://localhost:8080/insertDb1AndDb2?name=2&age=0

9、查看数据库,如果没有一条数据插入,代表分布式事务管理成功。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/az44yao/article/details/102463207

spring boot+mybatis+automatic+jta实现分布式事务_ccllcaochong1的博客-爱代码爱编程

分布式事务解决方案(即操作多个数据源事务解决方案): 有如下几种方案: automatic+jta ;两段提交协议 ;MQ推送 实现automatic+jta分布式事务管理: 1.添加依赖 <dependency> <groupId>org.springframework.bo

spring-boot入门(七)atomikos+druid+多数据源下的分布式事务配置_蓝墨49的博客-爱代码爱编程

spring-boot入门(七)atomikos+druid+多数据源下的分布式事务配置 本章内容是基于spring-boot入门(六)多数据源的基础之上进行的,如果还不了解多数据源怎么配置,请参考上一章节的内容。在上一章

springboot中使用jta+atomikos处理多数据源分布式事务问题_懒狗的自我救赎的博客-爱代码爱编程

springboot中使用jta+atomikos处理多数据源分布式事务问题 多数据源拆分思路: 例子:公司分为两个数据库,一个数据库专门存放共同配置文件,一个数据库是垂直业务数据库 垂直: 业务划分具体数据库 在一

springboot 分布式事务的解决方案(jta+atomic+多数据源)(^-爱代码爱编程

首先,到底啥是分布式事务呢,比如我们在执行一个业务逻辑的时候有两步分别操作A数据源和B数据源,当我们在A数据源执行数据更改后,在B数据源执行时出现运行时异常,那么我们必须要让B数据源的操作回滚,并回滚对A数据源的操作;这种情况在支付业务时常常出现;比如买票业务在最后支付失败,那之前的操作必须全部回滚,如果之前的操作分布在多个数据源中,那么这就是典型的分布式

分布式事务02-jta+atomikos解决分布式事务_沐宇熙的博客-爱代码爱编程_jta-atomikos

文章目录 1.基本概念1.1 Jta+Atomikos 简介1.2 XA协议1.3 JTA1.4 Atomikos 2.阶段提交协议2.1 两阶段提交协议2.2 三阶段提交协议2.3 2PC与3PC提交区别

这6种最常见分布式事务解决方案!请拿走不谢!_架构师小秘圈的博客-爱代码爱编程

作者:不清不慎,目前在杭州蘑菇街公司任职,Java大数据开发工程师一枚,热爱研究开源技术! 架构师社区合伙人! 一、分布式事务 分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。以上是百度百科的解释,简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布

springboot+jta+atomikos实现分布式事务-爱代码爱编程

springboot+jta+atomikos实现分布式事务 分布式系统中,会根据不同的业务,拆分出不同的系统和数据库,各个系统之间紧密联系,所以我们会经常遇到一个功能需要操作多个数据库的场景,例如商城下单功能,减库存是在

springBoot入门总结(八)使用 jta+atomikos 整合springBoot分布式事务-爱代码爱编程

一、JTA:Java Transaction Manager 事务是计算机应用中不可或缺的组件模型,它保证了用户操作的原子性 ( Atomicity )、一致性 ( Consistency )、隔离性 ( Isolation ) 和持久性 ( Durabilily )。 JTA:(Java Transaction Manager)是Java 中对事务进

多数据源解决分布式事务问题【SpringBoot+JTA+Atomikos】-爱代码爱编程

1:引入依赖 <!--java 事务api 阶段 是xa协议的java实现--> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jta-atomikos --> <dependency>

Jta+Atomikos解决分布式事务-爱代码爱编程

1.基本概念 1.1 Jta+Atomikos 简介 传统项目中,比如项目中使用到多数据源的时候大多数采用jta+Atomikos解决分布式事务问题,jta+Atomikos底层是基于XA协议的两阶段提交方案。 1.2 XA协议 XA 事务的基础是两阶段提交协议。分为以下两阶段 需要有一个事务协调者来保证所有的事务参与者都完成了准备工作。

SpringBoot2 整合JTA组件,多数据源事务管理-爱代码爱编程

本文源码:GitHub·点这里 || GitEE·点这里 一、JTA组件简介 1、JTA基本概念 JTA即Java-Transaction-API,JTA允许应用程序执行分布式事务处理,即在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序对JTA的支持极大地增强了数据访问能力。 XA协议是数据库层面的一套分布式事务管理的规范,JTA是X

atomikos数据源报错Max number of active transactions reached-爱代码爱编程

问题 springboot项目使用的atomikos数据源。某次在生产环境执行逻辑时报错,查看日志发现如下错误 源码分析 通过日志发现报错是在TransactionServiceImpl中发生的,该类关键代码如下可知原因是map中保存的事务对象数量达到了默认值50,所以报错。 通过断点知道默认值是在如下配置中同时我们也可以覆盖默认配置,配置方式为在a

数据库并发控制-爱代码爱编程

数据库并发控制 单机2PL (2 Phase Locking)OCC (Optimistic Concurrency Control)MVCC (Multi Version Concurrency Control)分布式2PC(Two-phaseCommit)3PC(Three-phase commit)LCN(Lock Control Notif

SpringBoot+jta+atomikos来管理分布式事务、SpringBoot整合log4j日志、SpringBoot中使用Aop切面类统一处理Web请求写入日志-day02下下-爱代码爱编程

目录 6.6 SpringBoot中的多事务管理第一步:添加jta事务依赖第二步:修改数据库连接配置数据第三步:添加2个配置模型第四步:重写两个数据源的配置第五步:App启动程序中添加配置效果7. SpringBoot整合log4j第一步:导入Log4j属性文件第二步:pom中添加依赖第三步:测试8. SpringBoot中使用AOP统一处理Web

SpringBoot 11 jta+atomikos解决分布式事务-爱代码爱编程

1:JTA JTA(java Transaction API)是JavaEE 13 个开发规范之一。java 事务API,允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。事务最简单最直接的目的就是保证数据的有效性,数据的一致性。 2:atomikos  Atomik

springboot-jta-atomikos多数据源事务管理-爱代码爱编程

背景 我们平时在用springboot开发时,要使用事务,只需要在方法上添加@Transaction注解即可,但这种方式只适用单数据源,在多数据源下就不再适用; 比如在多数据源下,我们在一个方法里执行了数据源A的操作,又执行了数据源B的操作,如果报错了,事务只会回滚主数据源或者是指定事务的数据源数据(@Transactional(value="指定事务

分布式事务-spring_boot_jta_atomikos_飞起的蜗牛的博客-爱代码爱编程

同一个服务里面多个数据源事务事务一致性 编写本文的目的在与分享下在项目中利用atomikos解决同一个服务里面多个数据源事务事务一致性的问题的示例代码,题材来源于网络的文章和实际项目使用技术栈的组合。 1.关键pom文件

springboot之jpa框架下如何使用jta——分布式事务解决方案_王者之路001的博客-爱代码爱编程

以前,笔者写过一篇博客,支付宝DTS方案,当然,只是仅仅是简单讨论了下分布式事务的解决方案。PS:笔者看了下相关评论,发现由于太简单,被不少人Diss了一通。 最近,笔者在自己的工程上,试图一次性解决分布式事务问题。 笔者自身的工程,目前是Springboot作为基本框架,以JPA作为数据库操作工作。笔者首先想到的,是如何利用现有框架,以及成熟的方案,