故事场景
小红是个顾客,小明是卖白粉的。
小红找小明买白粉。
普通的事务
一手交钱一手交货。
小红给钱给小明,小明给白粉。
1、事务失败。
小红钱不够买白粉,小明退钱,小红退货。
分布式事务
1、两段提交(2PC)
现在疫情严峻,没办法直接线下一手交钱一手交货,小红和小明又不相互信任。
我给你钱你不给我货跑路怎么办。这时候引入XA协议,来个有权势的小黑,当中间人。
XA协议中包含着两个角色:事务协调者和事务参与者。
事务协调者是黑帮老大,事务参与者是小红,小明。
1、小黑发话了,小红钱准备好了没有,小明货呢。
2、小红:OK,我把钱放垃圾桶了。小明:OK,我把货放树后面
3、小黑去检查钱在不在,货在不在。
-------------------------第一阶段结束---------------------------
4、小黑告诉小明钱放垃圾桶,告诉小红货在树后面。
5、小红、小明分别拿到货告诉小黑没问题
---------------------------第二阶段结束交易成功结束------------------
XA失败
1、第一阶段一方没有按照规定放钱和货交易失败。
2、假如小红找错树了,没有找到货。小明拿到钱了,小红告诉小黑不行有内鬼交易取消。
3、小黑放话这次交易失败,小红拿回自己的钱,小明拿回自己的货。
XA两阶段提交的不足
1.性能问题
XA协议遵循强一致性。在事务执行过程中,各个节点占用着数据库资源,只有当所有节点准备完毕,事务协调者才会通知提交,参与者提交后释放资源。这样的过程有着非常明显的性能问题。
2.协调者单点故障问题
事务协调者是整个XA模型的核心,一旦事务协调者节点挂掉,参与者收不到提交或是回滚通知,参与者会一直处于中间状态无法完成事务。
3.丢失消息导致的不一致问题。
在XA协议的第二个阶段,如果发生局部网络问题,一部分事务参与者收到了提交消息,另一部分事务参与者没收到提交消息,那么就导致了节点之间数据的不一致。
1.XA三阶段提交3PC
XA三阶段提交在两阶段提交的基础上增加了CanCommit阶段,并且引入了超时机制。一旦事物参与者迟迟没有接到协调者的commit请求,会自动进行本地commit。这样有效解决了协调者单点故障的问题。但是性能问题和不一致的问题仍然没有根本解决
补偿事务(TCC)
Try 阶段(尝试阶段): 在这个阶段,系统尝试执行事务的各个分支操作,并且预留必要的资源。如果所有分支操作都执行成功,那么事务进入 Confirm 阶段。如果任何一个分支操作失败,那么事务进入 Cancel 阶段。
Confirm 阶段(确认阶段): 在这个阶段,系统执行之前 Try 阶段所预留的资源,确认事务的执行结果。如果所有分支操作都确认成功,那么事务完成。如果任何一个分支操作确认失败,那么事务进入 Cancel 阶段。
Cancel 阶段(取消阶段): 在这个阶段,系统回滚之前 Try 阶段所预留的资源,取消事务的执行。这个阶段用于补偿 Try 阶段中已经执行的操作,以确保事务的一致性。
TCC 模式的核心思想是通过将事务分解为可补偿的小事务,并在每个阶段(Try、Confirm、Cancel)中执行相应的操作来保证事务的一致性。这种模式可以在分布式系统中实现高可用性和容错性,但是也需要开发人员自行编写补偿逻辑,增加了开发复杂性。
在实践中,TCC 模式通常与分布式事务协调器(如 Seata、Himly、TCC-Transaction 等)一起使用,以简化事务管理和补偿逻辑的实现。