1. 简介
LCN框架在2017年6月发布第一个版本,目前最新已经达到5.0版本。
LCN早期设计时,1.0版本和2.0版本设计步骤如下:
- 锁定事务单元(Lock)
- 确认事务模块状态(Confirm)
- 通知事务(Notify)
取各自首字母后名称为LCN。
LCN框架从5.0开始兼容了LCN、TCC、TXC三种事务模式,为了和LCN框架区分,从5.0开始把LCN框架更名为:TX-LCN分布式事务框架。
2. TX-LCN原理
TX-LCN由两大模块组成,TxClient、TxManager。
TxClient作为模块的依赖框架,提供了TX-LCN的标准支持,事务发起方和参与方都属于TxClient。TxManager作为分布式事务的控制方,控制整个事务。
2.1 原理中核心内容
1) 创建事务组
是指在事务发起方开始执行业务代码之前先调用TxManager创建事务组对象,然后拿到事务标识GroupId的过程。
2) 加入事务组
添加事务组是指参与方在执行完业务方法以后,将该模块的事务信息通知给TxManager的操作。
3) 通知事务组
是指在发起方执行完业务代码以后,将发起方执行结果状态通知给TxManager,TxManager将根据事务最终状态和事务组的信息来通知相应的参与模块提交或回滚事务,并返回结果给事务发起方。
3. TX-LCN事务模式
Tx-LCN 5.0开始支持三种事务模式,分别是:LCN、TCC、TXC模式。
每种模式在实际使用时有着自己对应的注解。
- LCN:@LcnTransaction
- TCC:@TccTransaction
- TXC:@TxcTransaction
3.1. LCN模式
3.1.1. 原理介绍
LCN模式是通过代理JDBC中Connection的方式实现对本地事务的操作,然后在由TxManager统一协调控制事务。当本地事务提交回滚或者关闭连接时将会执行假操作,该代理的连接将由LCN连接池管理。
3.1.2 模式特点
- 该模式对代码的嵌入性低。
- 该模式仅限于本地存在连接对象且可通过连接对象控制事务的模块。
- 该模式下的事务提交与回滚是由本地事务方控制,对于数据一致性上有较高的保障。
- 该模式缺陷在于代理的连接需要随事务发起方一同释放连接,增加了连接占用的时间。
总结:LCN模式适合能用JDBC连接的所有支持事务的数据库
3.2. TCC事务模式
3.2.1 原理介绍
TCC事务机制相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。主要由三步操作,Try: 尝试执行业务、 Confirm:确认执行业务、 Cancel: 取消执行业务。
3.2.2 代码说明
每个TCC事务处理方法可以额外包含confirmXxx和cancelXxx的方法(),出现失败问题,需要在cancel中通过业务逻辑把改变的数据还原回来。
confirmXxx和cancelXxx 两个方法会由TxManager进行统一协调调用。
confirmXxx和cancelXxx也可以在@TccTransaction注解中通过属性明确指定。
@TccTransaction
public String demo(){
// 正常的service方法,也是Try尝试执行执行
}
public void confirmDemo(){
// 当demo方法没有出现异常时执行的方法
// 方法名称必须叫做confirm+代理方法首字母
}
public void cancelDemo(){
// 当demo方法出现异常时执行的方法
// 方法名称必须叫做cancel+代理方法首字母
}
3.2.3 模式特点
- 该模式对代码的嵌入性高,要求每个业务需要写二个以上步骤的操作。
- 该模式对有无本地事务控制都可以支持,使用面更广。
- 数据一致性控制几乎完全由开发者控制,对业务开发难度要求高。
总结:Tcc模式应用于所有不支持XA事务的软件。例如:redis,mongodb等
4. TXC事务模式
4.1 原理介绍
TXC模式命名来源于淘宝,实现原理是在执行SQL之前,先查询SQL的影响数据,然后保存执行的SQL信息和创建锁。当需要回滚的时候就采用这些记录数据回滚数据库,目前锁实现依赖redis分布式锁控制。(在使用lcn时必须要配置redis参数)
4.2 模式特点
- 该模式同样对代码的嵌入性低。
- 该模式仅限于对支持SQL方式的模块支持。
- 该模式由于每次执行SQL之前需要先查询影响数据,因此相比LCN模式消耗资源与时间要多。
- 该模式不会占用数据库的连接资源。
总结:只能用在支持SQL的数据库。对资源消耗较多。建议使用LCN模式
5. XA的两阶段提交方案(数据库支持分布式事务,为什么还用TX-LCN)
5.1. 什么是XA协议
XA协议由Oracle Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准。目前,Oracle、Informix、DB2和Sybase等各大数据库厂家都提供对XA的支持。XA协议采用两阶段提交方式来管理分布式事务。XA接口提供资源管理器与事务管理器之间进行通信的标准接口。
XA就是X/Open DTP定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。XA接口函数由数据库厂商提供。
X/Open组织(即现在的Open Group)定义了分布式事务处理模型。X/Open DTP模型(1994)包括应用程序(AP)、事务管理器(TM)、资源管理器(RM)、通信资源管理器(CRM)四部分。一般,常见的事务管理器(TM)是交易中间件,常见的资源管理器(RM)是数据库,常见的通信资源管理器(CRM)是消息中间件。
5.2. XA协议的一阶段提交
如果在程序中开启了事务,那么在应用程序发出提交/回滚请求后,数据库执行操作,而后将成功/失败返回给应用程序,程序继续执行。
一阶段提交协议相对简单。优点也很直观,它不用再与其他的对象交互,节省了判断步骤和时间,所以在性能上是在阶段提交协议中最好的。但缺点也很明显:数据库确认执行事务的时间较长,出问题的可能性就随之增大。如果有多个数据源,一阶段提交协议无法协调他们之间的关系。
5.3 XA协议的二阶段提交
在一阶段协议的基础上,有了二阶段协议,二阶段协议的好处是添加了一个管理者角色。
很明显,二阶段协议通过将两层变为三层,增加了中间的管理者角色,从而协调多个数据源之间的关系,二阶段提交协议分为两个阶段。
应用程序调用了事务管理器的提交方法,此后第一阶段分为两个步骤:
- ① 事务管理器通知参与该事务的各个资源管理器,通知他们开始准备事务。
- ② 资源管理器接收到消息后开始准备阶段,写好事务日志并执行事务,但不提交,然后将是否就绪的消息返回给事务管理器(此时已经将事务的大部分事情做完,以后的内容耗时极小)。
第二阶段也分为两个步骤:
- ① 事务管理器在接受各个消息后,开始分析,如果有任意其一失败,则发送回滚命令,否则发送提交命令。
- ② 各个资源管理器接收到命令后,执行(耗时很少),并将提交消息返回给事务管理器。
事务管理器接受消息后,事务结束,应用程序继续执行。
为什么要分两步执行?一是因为分两步,就有了事务管理器统一管理的机会;二是尽可能晚地提交事务,让事务在提交前尽可能地完成所有能完成的工作,这样,最后的提交阶段将是耗时极短,耗时极短意味着操作失败的可能性也就降低。
同时,二阶段提交协议为了保证事务的一致性,不管是事务管理器还是各个资源管理器,每执行一步操作,都会记录日志,为出现故障后的恢复准备依据。
缺点:
- 二阶段提交协议的存在的弊端是阻塞,因为事务管理器要收集各个资源管理器的响应消息,如果其中一个或多个一直不返回消息,则事务管理器一直等待,应用程序也被阻塞,甚至可能永久阻塞。
- 两阶段提交理论的一个广泛工业应用是XA协议。目前几乎所有收费的商业数据库都支持XA协议。XA协议已在业界成熟运行数十年,但目前它在互联网海量流量的应用场景中,吞吐量这个瓶颈变得十分致命,因此很少被用到。