java 事务_Java分布式事务实现Atomikos

先了解X/Open DTP(Distributed Transaction Processing)模型

X/Open DTP模型与XA规范

X/Open,即现在的open group,是一个独立的组织,主要负责制定各种行业技术标准。官网地址:www。opengroup。org。X/Open组织主要由各大知名公司或者厂商进行支持,这些组织不光遵循X/Open组织定义的行业技术标准,也参与到标准的制定。下图展示了open group目前主要成员(官网截图):

b464fe67b702cf62ae8ba4655bc93ed1.png

针对DTP,X/Open提供了以下参考文档:

DTP 参考模型:

83b93388b596bcf58905235c8a596eaa.png

DTP XA规范:

26d303a63b38d8f8bb7a8f15e6367f13.png

DTP模型

1、模型元素

在<>第3版中,规定了构成DTP模型的5个基本元素:

应用程序(Application Program ,简称AP):用于定义事务边界(即定义事务的开始和结束),并且在事务边界内对资源进行操作。

资源管理器(Resource Manager,简称RM):如数据库、文件系统等,并提供访问资源的方式。

事务管理器(Transaction Manager ,简称TM):负责分配事务唯一标识,监控事务的执行进度,并负责事务的提交、回滚等。

通信资源管理器(Communication Resource Manager,简称CRM):控制一个TM域(TM domain)内或者跨TM域的分布式应用之间的通信。

通信协议(Communication Protocol,简称CP):提供CRM提供的分布式应用节点之间的底层通信服务。

一个DTP模型实例,至少有3个组成部分:AP、RMs、TM。如下所示:

8749eac2e0ad5dbd9a172656c082ac65.png

这张图类似于我们之前提到的跨库事务的概念,即单个应用需要操作多个库。在这里就是一个AP需要操作多个RM上的资源。AP通过TM来声明一个全局事务,然后操作不同的RM上的资源,最后通知TM来提交或者回滚全局事务。

XA规范

在DTP本地模型实例中,由AP、RMs和TM组成,不需要其他元素。AP、RM和TM之间,彼此都需要进行交互,如下图所示:

9633d8804e6965cd4d1ecce9852ec3db.png

这张图中(1)表示AP-RM的交互接口,(2)表示AP-TM的交互接口,(3)表示RM-TM的交互接口。关于这张图,XA规范有以下描述:

The subject of this X/Open specification is interface (3) in the diagram above, the XA interface by which TMs and RMs interact.

For more details on this model and diagram, including detailed definitions of each component, see the referenced DTP guide.

也就是说XA规范的最主要的作用是,就是定义了RM-TM的交互接口,下图更加清晰了演示了XA规范在DTP模型中发挥作用的位置,从下图中可以看出来,XA仅仅出现在RM和TM的连线上。

55b0b1c71db564c7c4b1b3235c4a5058.png

XA规范除了定义的RM-TM交互的接口(XA Interface)之外,还对两阶段提交协议进行了优化。 一些读者可能会误认为两阶段提交协议是在XA规范中提出来的。事实上: 两阶段协议(two-phase commit)是在OSI TP标准中提出的;在DTP参考模型(<>)中,指定了全局事务的提交要使用two-phase commit协议;而XA规范(<< Distributed Transaction Processing: The XA Specification>>)只是定义了两阶段提交协议中需要使用到的接口,也就是上述提到的RM-TM交互的接口,因为两阶段提交过程中的参与方,只有TM和RMs。参见<> 第3版 2.1节,原文如下:

Commitment Protocol

A commitment protocol is the synchronisation that occurs at transaction completion. The X/Open DTP Model follows the two-phase commit with presumed rollback1 protocol defined in the referenced OSI TP standards. A description of the basic protocol is given in Section 3.4.3 on page 13. In certain cases, a global transaction may be completed heuristically. Heuristic transaction completion is described in Section 3.4.5 on page 14.

XA Interface

XA规范中定义的RM 和 TM交互的接口如下图所示:

e5afe74c2a86c24abc85e844323606d9.png

两阶段提交协议(2PC):

两阶段提交协议(Two Phase Commit)不是在XA规范中提出,但是XA规范对其进行了优化,因此统一放到这里进行讲解。而从字面意思来理解,Two Phase Commit,就是将提交(commit)过程划分为2个阶段(Phase):

b900f30abab1333f3813c285afd564df.png

阶段1:

TM通知各个RM准备提交它们的事务分支。如果RM判断自己进行的工作可以被提交,那就就对工作内容进行持久化,再给TM肯定答复;要是发生了其他情况,那给TM的都是否定答复。在发送了否定答复并回滚了已经的工作后,RM就可以丢弃这个事务分支信息。

以mysql数据库为例,在第一阶段,事务管理器向所有涉及到的数据库服务器发出prepare"准备提交"请求,数据库收到请求后执行数据修改和日志记录等处理,处理完成后只是把事务的状态改成"可以提交",然后把结果返回给事务管理器。

阶段2

TM根据阶段1各个RM prepare的结果,决定是提交还是回滚事务。如果所有的RM都prepare成功,那么TM通知所有的RM进行提交;如果有RM prepare失败的话,则TM通知所有RM回滚自己的事务分支。

以mysql数据库为例,如果第一阶段中所有数据库都prepare成功,那么事务管理器向数据库服务器发出"确认提交"请求,数据库服务器把事务的"可以提交"状态改为"提交完成"状态,然后返回应答。如果在第一阶段内有任何一个数据库的操作发生了错误,或者事务管理器收不到某个数据库的回应,则认为事务失败,回撤所有数据库的事务。数据库服务器收不到第二阶段的确认提交请求,也会把"可以提交"的事务回撤。

两阶段提交协议(2PC)存在的问题:

1、同步阻塞问题

在二级段提交的执行过程中,所有参与该事务操作的逻辑的都在阻塞状态,也就是说,各个参与者在等待其他参与者响应的过程中,将无法进行其他的任务操作。

2、单点故障

由于协调者的重要性,一旦协调者TM发生故障。参与者RM会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)。

3、数据不一致

在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这会导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据不一致性的现象。

Java 事务编程接口(JTA:Java Transaction API)和 Java 事务服务 (JTS;Java Transaction Service) 为 J2EE 平台提供了分布式事务服务。分布式事务(Distributed Transaction)包括事务管理器(Transaction Manager)和一个或多个支持 XA 协议的资源管理器 ( Resource Manager )。我们可以将资源管理器看做任意类型的持久化数据存储;事务管理器承担着所有事务参与单元的协调与控制。JTA 事务有效地屏蔽了底层事务资源,使应用可以以透明的方式参入到事务处理中;但是与本地事务相比,XA 协议的系统开销大,在系统开发过程中应慎重考虑是否确实需要分布式事务。若确实需要分布式事务以协调多个事务资源,则应实现和配置所支持 XA 协议的事务资源,如 JMS、JDBC 数据库连接池等。

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

Atomikos公司官方网址为:

fead86d4c91deeee540be196483a501e.png

。其旗下最著名的产品就是事务管理器。产品分两个版本:

TransactionEssentials:开源的免费产品

ExtremeTransactions:上商业版,需要收费。

这两个产品的关系如下图所示:

cb8333f0e788562b6741efae56c032c8.png

TransactionEssentials:

1、实现了JTA/XA规范中的事务管理器(Transaction Manager)应该实现的相关接口,如:

UserTransaction实现是com.atomikos.icatch.jta.UserTransactionImp,用户只需要直接操作这个类

TransactionManager实现是com.atomikos.icatch.jta.UserTransactionManager

Transaction实现是com.atomikos.icatch.jta.TransactionImp

2、针对实现了JDBC规范中规定的实现了XADataSource接口的数据库连接池,以及实现了JMS规范的MQ客户端提供一层封装。

XADataSource、XAConnection等接口应该由资源管理器RM来实现,而Atomikos的作用是一个事务管理器(TM),并不需要提供对应的实现。而Atomikos对XADataSource进行封装,只是为了方便与事务管理器整合。封装XADataSource的实现类为AtomikosDataSourceBean。

Atomikos以jar包的形式集成到项目中即可,也就是不需要另外启动一个单独的事务管理器进程,例如:seata需要单独的一个服务进程。

代码:

public class AtomikosDemo {public static AtomikosDataSourceBean createDs1() {AtomikosDataSourceBean ds = new AtomikosDataSourceBean() ;ds.setUniqueResourceName("tksResource") ;ds.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource") ;Properties xaProperties = new Properties() ;xaProperties.setProperty("url", "jdbc:mysql://localhost:3306/tks?useSSL=false&serverTimezone=UTC") ;xaProperties.setProperty("user", "root") ;xaProperties.setProperty("password", "123123") ;ds.setXaProperties(xaProperties) ;ds.setMinPoolSize(10) ;ds.setMaxPoolSize(10) ;ds.setBorrowConnectionTimeout(30) ;ds.setMaxLifetime(60) ;ds.setMaintenanceInterval(60) ;return ds ;}public static AtomikosDataSourceBean createDs2() {AtomikosDataSourceBean ds = new AtomikosDataSourceBean() ;ds.setUniqueResourceName("testjapResource") ;ds.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource") ;Properties xaProperties = new Properties() ;xaProperties.setProperty("url", "jdbc:mysql://localhost:3306/testjpa?useSSL=false&serverTimezone=UTC") ;xaProperties.setProperty("user", "root") ;xaProperties.setProperty("password", "123123") ;ds.setXaProperties(xaProperties) ;ds.setMinPoolSize(10) ;ds.setMaxPoolSize(10) ;ds.setBorrowConnectionTimeout(30) ;ds.setMaxLifetime(60) ;ds.setMaintenanceInterval(60) ;return ds ;}public static void main(String[] args) throws Exception {AtomikosDataSourceBean ds1 = createDs1() ;AtomikosDataSourceBean ds2 = createDs2() ;Connection conTks = null;Connection conTestJpa = null ;PreparedStatement psTks = null ;PreparedStatement psTestJpa = null ;UserTransaction tx = new UserTransactionImp() ;try {tx.begin() ;conTks = ds1.getConnection() ;psTks = conTks.prepareStatement("update users set score = 77777 where id = ?") ;psTks.setInt(1, 1) ;int tksRes = psTks.executeUpdate() ;System.out.println("tks 执行结果:" + tksRes) ;System.out.println(1 / 0) ;conTestJpa = ds2.getConnection() ;psTestJpa = conTestJpa.prepareStatement("update users set password = '888888' where id = ?") ;psTestJpa.setInt(1, 2) ;int testJpaRes = psTestJpa.executeUpdate() ;System.out.println("testJpa 执行结果:" + testJpaRes) ;tx.commit() ;} catch (Exception e) {e.printStackTrace() ;tx.rollback() ;} finally {if (psTks != null) {psTks.close(); }if (psTestJpa != null) {psTestJpa.close() ;}}}}

在springboot中 加入如下依赖:

org.springframework.bootspring-boot-starter-jta-atomikos

分别配置数据源信息即可。

完毕!!!

分布式事务框架Seata之AT模式

SpringBoot+Atomikos多数据源分布式事务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值