Welcome everyone

分布式事务理论

分布式 汪明鑫 146浏览 0评论

ACID

单机数据库事务ACID

  • Atomic(原子性)     事务必须是原子的工作单元
  • Consistent(一致性)  事务完成时,必须使所有数据都保持一致状态
  • Isolation(隔离性)    并发事务所做的修改必须和其他事务所做的修改是隔离的
  • Duration(持久性) 事务完成之后,对系统的影响是永久性的

 

为什么会产生分布式事务

  • SOA
  • 分库分表

 

 

下单需要rpc调用支付服务和扣减库存服务,已经不在一个服务进程内,且涉及操作多个db

传统的ACID已经无法满足,因此引入了分布式事务

要么支付和扣减库存一起成功,要么一起失败,不会出现数据不一致性,不允许既有成功又有失败的中间状态

 

刚性分布式事务

数据强一致性

CP模型

 

【XA模型】

AP application   应用
RM resouces manager   资源管理器。 数据库
TM transaction manager  事务管理器,事务协调者

 

 

可以说XA是一种规范

 

衍生的2种方案,2阶段提交和三阶段提交

 

-2PC  两阶段提交-

整个事务流程分为两个阶段,准备阶段(Prepare phase)、提交阶段(commit phase),2是指两个阶段,P是指准备阶段,C是指提交阶段

 

成功的情况

 

失败的情况

 

2pc存在的缺陷:

1、同步阻塞:最大的问题及同步阻塞,所有参与事务的逻辑均处于阻塞状态。

2、单点:协调者存在单点问题,如果协调者出现故障,参与者将一直处于锁定状态。

当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态

3、脑裂:在阶段2中,如果只有部分参与者接收并执行了Commit请求,会导致节点数据不一致

 

2pc很少用,性能差,存在很多问题

 

-3PC  三阶段提交-

阶段一:canCommit
阶段二:preCommit
阶段三:doCommit

 

改进点
a) 增加了超时机制
b) 第二阶段,如果协调者超时没有接受到参与者的反馈,则自动认为失败,发送abort命令
c) 第三阶段,如果参与者超时没有接受到协调者的反馈,则自动认为成功开始提交事务

 

相对于2PC,3PC主要解决的单点故障问题,并减少阻塞,因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态。
但是这种机制也会导致数据一致性问题,因为,由于网络原因,协调者发送的回滚命令没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到回滚命令并执行回滚的参与者之间存在数据不一致的情况。

在询问的时候并不锁定资源,除非所有人都同意了,才开始锁资源

 

 

柔性分布式事务

最终一致性、并发性高,性能更好

满足AP

CAP 、BASE理论

通过降低数据一致性,降低数据库资源的锁定时间,保证了CAP中的A可用性

且需要补偿接口保证数据最终一致性

 

 

【TCC模型】
Try-Confirm-Cancel

 

Try阶段:

完成所有业务检查(一致性),预留业务资源(准隔离性)

Confirm阶段:

确认执行业务操作,不做任何业务检查, 只使用Try阶段预留的业务资源。

Cancel阶段:

取消Try阶段预留的业务资源。

 

这样简单一看,是不是感觉TCC有点像XA的2PC

TCC两阶段提交与XA两阶段提交的区别是:

XA是资源层面的分布式事务,强一致性,在两阶段提交的整个过程中,一直会持有资源的锁。

XA事务中的两阶段提交内部过程是对开发者屏蔽的。事务管理器在两阶段提交过程中,从prepare到commit/rollback过程中,资源实际上一直都是被加锁的。如果有其他人需要更新这两条记录,那么就必须等待锁释放。

TCC是业务层面的分布式事务,最终一致性,不会一直持有资源的锁。

TCC中的两阶段提交并没有对开发者完全屏蔽,也就是说从代码层面,开发者是可以感受到两阶段提交的存在。开发者需要提供try、confirm、cancel三个接口。开发者明显的感知到了两阶段提交过程的存在。

try、confirm/cancel在执行过程中,一般都会开启各自的本地事务,来保证方法内部业务逻辑的ACID特性。

其中:

1、try过程的本地事务,是保证资源预留的业务逻辑的正确性。

2、confirm/cancel执行的本地事务逻辑确认/取消预留资源,以保证最终一致性,也就是所谓的补偿型事务(Compensation-Based Transactions)。

由于是多个独立的本地事务,因此不会对资源一直加锁。

 

 

TCC业务侵入大,实现成本高,一般用的较少

 

【Saga模型】
也是把分布式事务拆成多个本地事务
Saga是一个长活事务可被分解成可以交错运行的子事务集合。其中每个子事务都是一个保持数据库一致性的真实事务。
  • 每个Saga由一系列sub-transaction Ti 组成
  • 每个Ti 都有对应的补偿动作Ci,补偿动作用于撤销Ti造成的结果 (补偿回滚)

 

和TCC相比,Saga没有“预留”动作,它的Ti就是直接提交到库

 

Saga的执行顺序有两种:
  • T1, T2, T3, …, Tn
  • T1, T2, …, Tj, Cj,…, C2, C1,其中0 < j < n

 

Saga定义了两种恢复策略:
  • backward recovery,向后恢复,补偿所有已完成的事务,如果任一子事务失败。即上面提到的第二种执行顺序,其中j是发生错误的sub-transaction,这种做法的效果是撤销掉之前所有成功的sub-transation,使得整个Saga的执行结果撤销。
  • forward recovery,向前恢复,重试失败的事务,假设每个子事务最终都会成功。适用于必须要成功的场景,执行顺序是类似于这样的:T1, T2, …, Tj(失败), Tj(重试),…, Tn,其中j是发生错误的sub-transaction。该情况下不需要Ci。  (重试策略,保证所有子事务都成功,以至于确保分布式事务的成功)

 

显然,向前恢复没有必要提供补偿事务,如果你的业务中,子事务(最终)总会成功,或补偿事务难以定义或不可能,向前恢复更符合你的需求。
一般用的时向后恢复,进行失败补偿回滚
理论上补偿事务永不失败,然而,在分布式世界中,服务器可能会宕机,网络可能会失败,甚至数据中心也可能会停电。在这种情况下我们能做些什么? 最后的手段是提供回退措施,比如人工干预。
手动进行回滚

 

RocketMQ 事务消息功能实现分布式事务

通过发送半消息实现

 


MQ先发送半消息,MQ server端返回ACK,此时消息只是到MQ server,还没有发送给消费者

执行本地事务,本地事务执行成功,给MQ server 发送commit,真正触发消息投递到消费者

如果commit消息丢了,没有发送到MQ server 怎么办?

业务方需要提供一个反查本地事务状态的接口,定时去反查接口,来决定是commit或rollback

Half消息,就类似prepare

 

本地消息表实现分布式事务

用户注册后,即送皮肤

用户注册是操作在DB1,送皮肤是操作在DB2

不是简单的本地事务

分布式事务保证操作DB1、 DB2都成功

 

我们引入事件表 + MQ 解决分布式事务

什么是事件表,就是记录用户注册/送皮肤这个事件的状态

用户注册成功后,也要向user_evernt表插入一个对应的事件数据,并置当前状态为NEW

然后定时任务1 ,user_evernt扫表,取出NEW的数据进行送皮肤操作,

把送皮肤的消息发送到MQ,发送后把user_evernt状态置为PUBLISHED

处理送皮肤的服务接收到消息后,向reward_evernt表插入一条数据,并把状态置为PUBLISHED

然后定时任务2,reward_evernt扫表,取出PUBLISHED的数据进行操作,并把状态置为DONE

 

详细流程如下:

1,先写用户表,再写事件表( NEW),事件表内容content就是 用户ID + 奖励皮肤

2,定时任务扫事件表,取出NEW状态下的数据,把content发送到activeMQ,并把状态置为PUBLISHED

3,消费者接收消息后,写事件表,content就是从activeMQ中读到的消息,即用户ID + 奖励皮肤,状态为PUBLISHED

4,定时任务扫奖励事件表,取出状态为PUBLISHED的数据,然后再reward表新加一条数据,再把事件表中对应的数据状态置为PROCESSED

整个过程完成

这样就保证了两个数据源之间数据的最终一致性了

 

本文参考了大量的文章,着实有点难顶
关于分布式事务了解的不是很深刻,而且缺少实战经验
如有错误,敬请指正

 

分布式事务:Saga模式 – 简书
聊聊分布式事务,再说说解决方案 – Savorboard – 博客园
分布式事务探讨系列(五):saga方案_网络_lsblsb的专栏-CSDN博客
分布式事务 CAP 理解论证 解决方案_网络_weixin_40533111的博客-CSDN博客
利用事务消息实现分布式事务 – chenjianbin – 博客园
分布式事务之本地消息表 – CanntBelieve – 博客园

 
 

转载请注明:汪明鑫的个人博客 » 分布式事务理论

喜欢 (1)

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz