分布式事物解决方案

分布式事物产生原因:主要产生与在微服务系统中,数据库的垂直拆分或者是RPC远程调用,

不在同一个数据源中,而是多个数据源中,每个数据源的事物都是本地事物,互不影响。

所以当A服务的数据源的事物发生回滚,不会影响到B服务的数据源回滚,从而产生分布式事物问题,无法保证分布式通讯数据一致性问题。

分布式事物基本理论:基本遵循CPA理论或者Base理论,采用柔性事物特征,软状态或者最终一致性特点保证分布式事物一致性问题。

分布式事物常见解决方案:

1.2pc两段提交协议

2.3pc三段提交协议(弥补两端提交协议缺点)

3.TCC或者GTS(阿里)

4.消息中间件最终一致性

5.传统项目采用Jta(Java操作分布式事物XA接口)+atomikos 注意不适合于分布式常见、只适合多数据源情况下。

6.使用LCN解决分布式事物,理念“LCN并不生产事务,LCN只是本地事务的搬运工”。

2PC

2PC,将事务的提交过程分为:准备阶段和提交阶段。事务的发起者称协调者,事务的执行者称参与者。

  阶段1:准备阶段

1、协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待所有参与者答复。

2、各参与者执行事务操作,但不提交事务。

3、如参与者执行成功,给协调者反馈YES,即可以提交;如执行失败,给协调者反馈NO,即不可提交。

  阶段2:提交阶段

  此阶段分两种情况:所有参与者均反馈YES、或任何一个参与者反馈NO。

  所有参与者均反馈YES时,即提交事务。

  任何一个参与者反馈NO时,即中断事务。

  提交事务:(所有参与者均反馈YES)

1、协调者向所有参与者发出正式提交事务的请求(即Commit请求)。

2、参与者执行Commit请求,并释放整个事务期间占用的资源。

3、各参与者向协调者反馈Ack完成的消息。

4、协调者收到所有参与者反馈的Ack消息后,即完成事务提交。

中断事务:(任何一个参与者反馈NO)
1、协调者向所有参与者发出回滚请求(即Rollback请求)。
2、参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。
3、各参与者向协调者反馈Ack完成的消息。
4、协调者收到所有参与者反馈的Ack消息后,即完成事务中断。

  附如下示意图:

分布式事物(2PC,3PC,CAP,柔性与刚性事物,LCN)_分布式事务

分布式事物(2PC,3PC,CAP,柔性与刚性事物,LCN)_分布式事务_02

2PC的缺陷

1、同步阻塞:最大的问题即同步阻塞,即:所有参与事务的逻辑均处于阻塞状态。
2、单点:协调者存在单点问题,如果协调者出现故障,参与者将一直处于锁定状态。
3、脑裂:在阶段2中,如果只有部分参与者接收并执行了Commit请求,会导致节点数据不一致。
由于2PC存在如上同步阻塞、单点、脑裂问题,因此又出现了2PC的改进方案,即3PC。

3PC

3PC,三阶段提交协议,是2PC的改进版本,即将事务的提交过程分为CanCommit、PreCommit、do Commit三个阶段来进行处理。

  阶段1:CanCommit

1、协调者向参与者发出CanCommit请求,询问是否可以提交事务,并等待所有参与者答复。

2、参与者收到CanCommit请求后,如果认为可以执行事务操作,则反馈YES,否则反馈NO。

  阶段2:PreCommit

  此阶段分两种情况:

1、所有参与者均反馈YES,即执行事务预提交。

2、任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。

  事务预提交:(所有参与者均反馈YES时)

1、协调者向所有参与者发出PreCommit请求,进入准备阶段。

2、参与者收到PreCommit请求后,执行事务操作,但不提交事务。

3、各参与者向协调者反馈Ack响应或No响应,并等待最终指令。

  中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)

1、协调者向所有参与者发出abort请求。

2、无论收到协调者发出的abort请求,或者在等待协调者请求过程中出现超时,参与者均会中断事务。

  阶段3:do Commit

  此阶段也存在两种情况:

1、所有参与者均反馈Ack响应,即执行真正的事务提交。

2、任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。

  提交事务:(所有参与者均反馈Ack响应时)

1、如果协调者处于工作状态,则向所有参与者发出do Commit请求。

2、参与者收到do Commit请求后,会正式执行事务提交,并释放整个事务期间占用的资源。

3、各参与者向协调者反馈Ack完成的消息。

4、协调者收到所有参与者反馈的Ack消息后,即完成事务提交。

  中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)

1、如果协调者处于工作状态,向所有参与者发出abort请求。

2、参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。

3、各参与者向协调者反馈Ack完成的消息。

4、协调者收到所有参与者反馈的Ack消息后,即完成事务中断。

  注意:进入阶段三后,无论协调者出现问题,或者协调者与参与者网络出现问题,都会导致参与者无法接收到协调者发出的do Commit请求或abort请求。此时,参与者都会在等待超时之后,继续执行事务提交。

  附示意图如下:

分布式事物(2PC,3PC,CAP,柔性与刚性事物,LCN)_协调者_03

3PC的优点和缺陷

优点:降低了阻塞范围,引入了超时机制,在等待超时后协调者或参与者会中断事务。

缺陷:脑裂问题依然存在,即在参与者收到PreCommit请求后等待最终指令,如果此时协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。

 

分布式领域CAP理论

C(一致性), 数据一致更新,所有数据变动都是同步的

A(可用性), 好的响应性能(指系统能够很好的为用户服务,访问超时等用户体验不好的情况)

P(分区容忍性) 可靠性(遇到某节点或网络分区故障时,仍然能够对外提供满足一致性和可用性的服务。)

定理:任何分布式系统只可同时满足二点,没法三者兼顾。

关系数据库的ACID模型拥有 高一致性 + 可用性 很难进行分区:

Atomicity原子性:一个事务中所有操作都必须全部完成,要么全部不完成。

Consistency一致性. 在事务开始或结束时,数据库应该在一致状态。

Isolation隔离层. 事务将假定只有它自己在操作数据库,彼此不知晓。

Durability. 一旦事务完成,就不能返回。

跨数据库两段提交事务:2PC (two-phase commit), 2PC is the anti-scalability pattern (Pat Helland) 是反可伸缩模式的,JavaEE中的JTA事务可以支持2PC。因为2PC是反模式,尽量不要使用2PC,使用BASE来回避。

BASE模型反ACID模型,完全不同ACID模型,牺牲高一致性,获得可用性或可靠性:

BASE思想主要强调基本的可用性,如果你需要High 可用性,也就是纯粹的高性能,那么就要以一致性或容忍性为牺牲,BASE思想的方案在性能上还是有潜力可挖的。、

分布式事物(2PC,3PC,CAP,柔性与刚性事物,LCN)_分布式事务_04

柔性事务和刚性事务

柔性事务满足BASE理论(基本可用,最终一致)
刚性事务满足ACID理论

柔性事务分为两阶段型,补偿型,异步确保型。最大努力通知型几种。

由于支付宝整个架构是SOA架构,因此传统单机环境下数据库的ACID事务满足了分布式环境下的业务需要,以上几种事务类似就是针对分布式环境下业务需要设定的。

软状态:状态有一段时间可以不同步,异步的。

LCN分布式事务框架

框架介绍

LCN分布式事务框架其本身并不创建事务,而是基于对本地事务的协调从而达到事务一致性的效果。

核心步骤

  1. 创建事务组
    是指在事务发起方开始执行业务代码之前先调用TxManager创建事务组对象,然后拿到事务标示GroupId的过程。
  2. 添加事务组
    添加事务组是指参与方在执行完业务方法以后,将该模块的事务信息添加通知给TxManager的操作。
  3. 关闭事务组
    是指在发起方执行完业务代码以后,将发起方执行结果状态通知给TxManager的动作。当执行完关闭事务组的方法以后,TxManager将根据事务组信息来通知相应的参与模块提交或回滚事务。

LCN事务控制原理是由事务模块TxClient下的代理连接池与TxManager的协调配合完成的事务协调控制。

TxClient的代理连接池实现了​​javax.sql.DataSource​​​接口,并重写了​​close​​方法,事务模块在提交关闭以后TxClient连接池将执行"假关闭"操作,等待TxManager协调完成事务以后在关闭连接。

分布式事物(2PC,3PC,CAP,柔性与刚性事物,LCN)_回滚_05

分布式事物(2PC,3PC,CAP,柔性与刚性事物,LCN)_回滚_06

 

分布式事物(2PC,3PC,CAP,柔性与刚性事物,LCN)_回滚_07