分布式事务的二阶段提交和三阶段提交

分布式事务:是指存在多个跨库事务的事务一致性问题,或者是指分布式架构下由多个应用节点组成的多个事务之间的事务一致性问题。

在单点服务时,某电商会员购买上市时会出现以下情况

  1. 开启数据库事务
  2. 创建订单
  3. 会员积分减少
  4. 商品库存减少
  5. 提交数据库事务

这样的话,在一个数据库事务中,就可以完成所有操作,利用数据库的原子保证了所有数据那么全部处理成功,要么全部回滚撤销,但是放在以微服务为代表的分布式架构下,问题就没有那么简单了,下面是一个分布式应用的示意图

分布式事务的二阶段提交和三阶段提交_第1张图片

 可以看到,商城应用作为业务的发起者,分别向订单服务、会员服务、库存服务发起了调用,而这些服务又有自己独立的数据存储,因为在物理上,各个数据库服务器都是独立的,每一个操作都会创建独立的事务,这就意味着在分布式事务处理时,无法通过单点数据库利用一个事务保证数据的完整性,我们必须引入某种机制来协调多个事务,要么全部提交,要么全部回滚,以此保证事务的完整性,这就是分布式事务的由来,在分布式事务中,有两种经典的解决方案:二阶段提交和三阶段提交


二阶段提交

下面是二阶段提交的第一个阶段:事务预处理阶段

分布式事务的二阶段提交和三阶段提交_第2张图片

 相比较于单点事务,分布式事务中新增了一个角色——事务协调者,它的职责时协调各个分支事务的开启与提交、回滚的处理

以上图为例,订单创建后,首先事务协调者会向各服务下达处理本地事务的通知,所谓本地事务就是每个服务应该做的事情,如订单服务负责创建新的订单记录,会员服务负责增加会员的积分,库存服务负责减少库存,在这个阶段,被操作的所有数据都处于未提交的状态,会被本地数据库的排他锁锁定。当本地事务处理完成后,会通知事务协调者本地事务处理完毕,当事务协调者陆续收到订单服务、会员服务、库存服务的处理完毕通知后,并进入二阶段提交的提交阶段


提交阶段

分布式事务的二阶段提交和三阶段提交_第3张图片

 在提交阶段,事务协调者会向每一个服务下达提交命令,每个服务收到提交命令后,对阶段一中未提交的数据进行commint操作,完成数据最终的写入,之后服务向事务协调者上报事务提交成功的通知,当事务协调者收到所有服务提交成功的通知后,就意味着一次分布式事务处理成功,这便是二阶段提交的正常过程。

但是,假设在阶段一中,有任何一个服务因某种原因向事务协调者上报事务处理失败,就意味着整体事务处理出现问题,阶段二的操作就自动转为回滚处理,将所有未处理的数据撤销,还原以保证完整性

对于二阶段提交来说,它有一个致命问题,当阶段二某个服务因为网络原因无法收到事务协调者下达的命令,则未提交的数据会造成长时间堵塞,可能会导致系统崩溃

以下图为例

分布式事务的二阶段提交和三阶段提交_第4张图片

 如果在提交阶段,库存服务实例与事务协调者之间断网,提交指令无法下达,这会导致库存中飞科剃须刀商品记录会长期处于未提交的状态,因为这条记录被数据库排他锁长期独占,之后有其他线程访问飞科剃须刀库存数据,该线程就会长期处于堵塞状态,随着堵塞线程的不断增加,库存的服务会面临崩溃的风险,解决这个问题的办法是,在服务这一侧增加超时机制,过一段时间,被锁定的飞科剃须刀因超时自动执行提交操作,释放锁定资源,尽管这样做,可能会导致数据不一致,但比线程挤压导致服务崩溃要好

为了解决二阶段的问题,三阶段提交的方案就出现了


三阶段提交

 三阶段提交实质是将二阶段提交中的提交阶段拆分为预提交阶段与提交阶段,同时在服务端都引入超时机制,保证数据库资源不会被长时间锁定

 下面是三阶段提交的第一个阶段:事务预处理阶段

分布式事务的二阶段提交和三阶段提交_第5张图片

阶段一:事务预处理阶段

3pc的事务预处理阶段与2pc的事务预处理阶段是一样的,用于处理本地事务,锁定数据库资源,当所有服务返回成功后,进入阶段二


阶段二:预提交阶段

分布式事务的二阶段提交和三阶段提交_第6张图片 预提交阶段只是一个询问机制,已确认所有服务已准备好,同时事务协调者与参与者都设置了超时时间,防止出现资源长时间被锁定,当阶段二所有服务返回可以提交,进入阶段三——提交阶段


阶段三:提交阶段 

分布式事务的二阶段提交和三阶段提交_第7张图片

 

3pc的提交阶段与2pc的提交阶段是一致的,在每一个数据库中,执行提交,实现资源的写入,如果事务协调者与服务通信中断导致无法提交,在服务端超时后自动执行提交操作,来保证资源释放


通过对比,我们发现,三阶段提交是二阶段提交的优化版本,主要通过加入预提交阶段引入超时机制,让数据库不会被长期锁定,但这也带来一个新问题,数据一致性可能因为超时后的强制提交被破坏,对于这个问题,有的方案是增加异步的数据补偿任务,日中跑批前的数据补偿,更完善的业务数据完整性的校验代码,引入数据监控及时通知人工补录

分布式事务常见的解决方案:

第一种:基于XA协议的强一致性事务方案

Atomic

Seata里面的XA事务模型

基于CAP理论可以知道,如果要保证分布式事务的强一致性,就必然会带来性能上的影响,从而去影响到可用性,所以强一致性事务的性能会比较低,

第二种:基于BASE理论下的弱一致性事务解决方案

比如说TCC事务模型以及基于可靠性消息的最终数据一致性,Seata的Saaga事务模型

最终一致性事务损失数据的强一致性,然后通过异步补偿的方式去达到数据的最终一致性,在性能上会比强一致性事务要好很多,所以适合在一些并发量比较高的场景里

你可能感兴趣的:(分布式,数据库,java)