分布式事务

共计 1584 个字符,预计需要花费 4 分钟才能阅读完成。

事务的概念

事务:事务是由一组操作构成的可靠的独立的工作单元,具备ACID的特性,并由类似begin transaction和end transaction语句或者函数界定。

ACID特性:原子性,一致性,隔离性,持久性

  • 原子性(atomicity):一个事务为不可分割的工作单位,要么都做,要么都不做
  • 一致性(consistency):事务必须是使数据库从一个一致性状态变成另一个一致性状态。
  • 隔离性(isolation):一个事务的执行不能被其他事务干扰。
  • 持久性(durability):一个事务一旦提交,它对数据库中数据的改变就是永久性的。

分布式事务

  • 基于XA协议的两段式提交(2pc)
  • 三段式提交(3pc)
  • Try Confirm Cancel(TCC)
  • MQ事务消息(可靠事件模式)
  • MQ非事务消息(加独立消息服务/本地事务表)
  • 柔性事务(最大努力通知/补偿)
  • Sagas(长事务)

下面介绍其中的几种

基于XA协议的两段式提交(2pc)

在分布式系统中,每个节点可以知道自己的操作是否成功或失败,但是无法知道其他节点的操作的成功或失败。当一个事务跨多个服务时,需要引入一个协调者组件来掌控所有节点(参与者)的操作结果,并将最终指示这些节点是否进行真正的提交。

分布式事务

工作流程
1)第一阶段

  1. 协调者会问参与者节点是否可以进行提交操作
  2. 各个参与者开始执行事务前的准备工作:资源上锁,预留资源等
  3. 各个参与者回应协调者,如果事务准备工作成功,就回应“可以提交”,否则回应“拒绝提交”

2)第二阶段

  1. 如果所有参与者回应“可以提交”,那么协调者向所有参与者发布“正式提交”的命令。参与者完成正式提交,并释放所有资源,回应“完成”,协调者收集所有“完成”回应后并结束这次全局事务
  2. 如果有一个或多个参与者回应“拒绝提交”,那么,协调者向所有参与者发送“回滚操作”,并释放所有资源,并回应“回滚完成”,协调者收集各参与者的回应后,取消全局事务

缺陷

  • 同步阻塞:参与节点是事务阻塞型的,事务过程中公共资源得不到释放,并发上不去
  • 单点故障:协调者发生故障,在未选举出新的协调者之前,参与者会一直阻塞下去
  • 网络抖动导致脑裂现象(过半机制就是为了防止脑裂问题),导致事务参与者不能很好的执行协调者的指令,出现数据不一致的现象
  • 二阶段无法解决的问题:协调者再发出commit消息后宕机,参与者收到消息后也宕机,就算再选举出新的协调者,也无法知道这个参与者的事务状态是否提交

三段式提交(3pc)

相比2pc的区别

  • 引入了超时机制,同时在参与者和协调者中引入超时机制
  • 在第一阶段和第二阶段插入一个准备阶段,就是将2pc的准备阶段再一分为二,形成cancommit,precommit,docommit三个阶段,就不详细介绍

MQ事务消息(可靠事件模式)

在常见的消息中间里RocketMQ是支持事务消息的,类似采用的二阶段提交,而RabbitMQ和kafka是不支持的。

分布式事务

实现思路

  1. 发送一条消息,rocketMQ将这条消息标记为Prepared,此时这条消息消费者是无法消费到的
  2. 执行业务逻辑代码,可能是一个本地数据库事务操作
  3. 确认发送消息,这个时候,RocketMQ将这条消息标记为可消费
  4. 如果确认发送失败,RocketMQ会定期扫描集群中的Prepared消息,然后按照事先配置好的策略,进行回滚或者发送确认消息

优点:实现了最终的一致性,不需要依赖本地数据库事务

缺点:实现难度大,且不通用,其他MQ不支持

MQ非事务消息(加独立消息服务/本地事务表)

生产发消息到一个独立的消息服务或本地事务表中

分布式事务

思路

  • 生产者将消息发送到一个自己写的独立服务中,处于prepare状态
  • 业务逻辑处理成功后,确认发送消息,才会将消息发送到消息队列中
  • consumer处理好消息后,返回ack给消息队列和独立消息服务,独立消息服务把这条消息删除,定时扫描prepare的消息,向producer确认是否发送
正文完
 
Dustin
版权声明:本站原创文章,由 Dustin 2020-02-12发表,共计1584字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。