分布式事务解决方案分类
1. 刚性事务
需要所有的参与者都执行ok之后再一起提交,致命的问题就是性能问题
2. 柔性事务
满足基本可用和最终一致性
cap理论 针对分布式系统来说
1. C 一致性
2. A 可用性
3. P 分区容错性
在分布式架构下,分区容错性是基本要求,否则就失去了分布式的价值,
CA或者CAP是不能满足的,原因是网络通信是不完全可靠的,如果是CA或者CAP同时满足就意味着 当出现网络分区的时候为了满足C一致性,就必须阻塞,或者拒绝客户的请求,这时就不满足A可用性,所以不能有CA的组合 只能是CP或者AP
大多数web系统对强一致性要求不是很高,所以大部分会考虑实现可用性,和分区容错性AP
如果采用CP就可能让用户等待很长的响应时间,或者永久阻塞
base理论
基本可用/柔性事务/最终一致性
是对cap理论一致性和可用性权衡的结果,核心思想:虽然无法做到强一致性,但是每个业务根据自身特点,采用适当的方式来达到最终一致性
分布式事务的理论模型,都是强一致性的
二阶段提交
流程:
1. AP应用程序通知TM开启事务
2. TM分配全局事务id并分配给管理的RM们
3. RM接到通知会分别开启事务并执行 如果成功就在commit阶段阻塞,并返回给RM成功信息
4. TM等待所有的RM回复成功之后,会通知所有的RM commit,有一方RM返回失败TM,就通知所有的RM回滚
缺点:
1. 同步阻塞,等待RM的命令才能执行
2. 过于保守,任何一个节点失败都会回滚
3. 如果TM在接收到RM返回的结果后发生故障 那么所有的RM都会处于阻塞状态
4. 如TM想所有的RM发送commit指令,这时只有一部分收到消息,此时一致性失效
三阶段提交
1. canCommit TM向RM发送询问确认RM是否正常,这阶段会有超时机制
2. preCommit 如果RM全部返回正常,TM会想所有的RM发送通知,RM开始写redo undo 执行事务操作 但是不commit,返回TM处理完成等待下一步指示
3. TM根据上一步RM返回的结果,来决定是commit还是rollback
与二阶段不同的是,三阶段多了一个canCommit阶段,目的是今早发现RM不能执行操作,超时会任务超时方执行成功,避免永久阻塞
基于base理论的柔性事务,分布式事务常见的解决方案
TCC(try confim cancel)补偿型方案
1. try 这个阶段是对数据的校验和资源的预留
2. confirm 操作try预留的资源 执行真正的操作
3. cancel 取消执行,解冻冻结的资源
举个例子: 就以转账为例
玉田给刘英转100块钱,在try阶段会分别冻结玉田和刘英的账户,当冻结成功之后,confirm阶段让玉田账户-100 刘英账户+100 ,冻结失败就会释放冻结的资源
如果冻结成功,但是网络故障灯因素导致刘英没收到confirm通知,TCC事务框架会记录事务运行的各个阶段,和状态,tcc会进行重试,以达到数据的最终一致,对应到例子中的+-操作都需要实现幂等性
基于可靠性消息的最终一致性方案
主要是利用消息中间件的可靠性机制来实现数据的一致性投递的
还以玉田给刘英转钱为例:
1. 玉田发送一条转账消息到rocketMq中,这个消息是个half状态,不能被刘英消费,
2. 玉田开始在自己的账户上-100
3. 如果玉田减钱成功就像MQ中发送一条commit消息,让刘英可以消费到,如果减钱失败就发送cancel消息,让这条消息被删除
4. 如果玉田一直不给MQ发送成功或者失败的消息,MQ会定时去问玉田执行结果,根据执行结果来决定消息是否让刘英消费
5. 消息可以被消费之后,消息消费完成之后会发送一个确认标识给MQ标识该消息投递成功 刘英给自己账户+钱,
6. 如MQ没收到刘英的确认接收到消息的通知之后MQ会重复的给刘英发这条消息
最大努力通知型
以支付宝支付场景为例:
1. 商户创建一个支付请求向支付宝
2. 支付宝开启一个支付页给支付者,并记录这个支付交易
3. 支付完成后触发一个回调给商户,
4. 商户处理支付宝的回调,并返回支付宝一个ack
5. 如果支付宝未收到商户的ack,支付宝就定时回调商户知道超出次数
6. 支付宝还会留一个查询支付结果接口给商户,让商户主动查询