一、分布式事务-原子性
随着数据量不断的变大,单机所能处理的数据总归是有上限的,所以现阶段分布式的应用系统在各个领域中遍地生花。接下来我们就来聊一下分布式系统中非常重
要的特性分布式事务的原子性功能。之前没有了解过分布式相关知识的读者可以阅读以下专栏“分布式算法”。
问:那么什么是分布式原子性呢?
答:在分布式系统中,分布式事务是指跨越多个独立的计算机或服务节点的一系列操作。这些操作必须以原子性进行,要么全部执行成功,要么全部回滚,保持数
据的一致性和完整性。原子性是分布式事务的关键特性之一,它确保了事务的不可分割性和一致性。具体来说,原子性要求一个事务中的所有操作要么都成功地被提交,要么都被完全撤销。
让我看一下詹姆斯·尼古拉·格雷(James Nicholas "Jim" Gray)的定义吧:
Atomicity: Either all the changes from the transaction occur (writes, and messages sent), or none occur.
上面那段话还是比较难懂的,特别是messages sent,但是不妨碍我们理解核心思想即原子性要么全部做完,要么都不做。
例子:某天温州的小杨准备给北京的小李转10万块钱,结果因为x行系统故障,导致了小李获得了10万,并且小杨的账号没有减少10万,两个人开心的不行。
上述其实就是因为“小杨扣钱”和“小李获钱”的操作没有捆绑起来导致的后果,这种操作是会导致银行破产,要么被客户骂死,风险是极大的。
那么上述问题我们该如何解决呢?下面我们介绍一下如何解决该问题的两个协议(TCC和2PC),本次内容先介绍TCC,后续介绍2PC。
二、TCC协议
TCC 全称即Try-Confirm-Cancel,由Pat Helland于2007年在一篇名为“Life beyond Distributed Transactions: an Apostate’s Opinion”的论文中首次提出。
从名字中我们可以看出,其将事务分为三个步骤:尝试(Try)、确认(Confirm)和取消(Cancel),来确保分布式系统中的事务操作的可靠性和一致性。
-
Try:事务参与者会尝试(Try)预留所有必要的资源,并执行一些前置检查。如果所有的资源都可用且检查通过,则可以继续到下一个阶段。否则,如果任何资源不可用或检查失败,则事务参与者会返回错误或异常。
-
Confirm:事务参与者会提交之前预留的资源,并执行实际的业务逻辑操作。这些操作可能会修改数据库、发送消息等。如果所有操作都成功完成,事务参与者会发送确认(Confirm)信号。
-
Cancel :如果在确认阶段发生错误或者出现异常情况,需要进行事务的回滚。在取消阶段(Cancel),事务参与者会释放之前预留的资源,并执行相应的回滚操作,以使整个事务回滚到初始状态。
TCC只是一个协议,具体的实现还需要结合实际场景(考虑网络延迟、幂等性、重试机制等方面的问题)进行。
2.1 TCC角色
虽然TCC的实现很多细节,但是当中涉及了三个角色。
-
Transaction Initiator: 事务发起者是整个分布式事务的发起方,负责协调和控制整个事务的执行流程。它引导和驱动事务的执行,并与参与者节点进行通信,最终决定是否提交或回滚整个事务。
-
Transaction Participant:事务参与者是分布式事务中的各个执行单元,负责执行具体的事务操作。每个参与者都实现了与协调者交互的Try、Confirm和Cancel方法。在Try阶段,参与者预留资源并执行前置检查;在Confirm阶段,参与者执行实际的业务操作;在Cancel阶段,参与者回滚之前的操作。
-
Coordinator:协调者是事务发起者与事务参与者之间的中间节点,负责协调各个参与者的行为,确保整个事务的一致性和原子性。协调者与每个参与者节点进行通信,根据收集到的确认和取消信息,决定最终提交或回滚事务。(好多实现,去掉了这个角色,直接通过Transaction Initiator完成)
下面给出一个Orcale 事务架构师Todd Little案例,通过MicroTx的介绍角色。下图中的Microservice A即是Transaction Initiator,Microservice B和Microservice B即为Transaction Participant,而Coordinator就是协调者确保事务的一致和原子,让大家统一进行confirm和Cancel。
2.2 优缺点分析
优点:
-
TCC协议相对于传统的两阶段提交(2PC)协议,具有更好的可扩展性和灵活性。
-
具有更高的并发性和没有长时间的锁等待
缺点:
-
代码对业务逻辑的嵌入性太强
-
更高的开发需求,因为我们需要提供尝试/确认/取消接口。
2.2 案例说明
下面介绍TCC如何介绍开篇提出的问题。
-
正常交易流程
-
异常交易处理方式
首先尝试去锁定需要的资源,这时候由于Service C异常了,其try对应资源失败,返回no;Service B正常响应,返回yes。由于Transaction Participant中响应了no,那么事务管理器向所有Transaction Participant发出cannel指定,从而保障所有操作都不执行。
三、参考资料
1、詹姆斯·尼古拉·格雷关于事务的介绍 https://amturing.acm.org/info/gray_3649936.cfm
2、用go语言实现TCC https://betterprogramming.pub/a-tcc-distributed-transaction-made-easy-with-go-c0a38d2a8c44、
3、Making Try-Confirm/Cancel Easy with MicroTx https://blogs.oracle.com/database/post/making-try-confirmcancel-easy-with-microtx