最终一致性的常用做法
1、单数据库事务
利用数据库的事务特性来满足事务的一致性,这时候的一致性是强一致性的。
2、多数据库事务
针对多数据库事务可以根据二阶段提交协议,采用spring 3.0 + Atomikos + JTA进行支持;
3、基于事务型消息队列的最终一致性
借助消息队列,在处理业务逻辑的地方发送消息,业务逻辑处理成功后,提交消息,确保消息是发送成功的,之后消息队列投递来进行处理,如果成功,则结束,如果没有成功,则重试,直到成功,不过仅仅适用业务逻辑中,第一阶段成功,第二阶段必须成功的场景。
4、基于消息队列+定时补偿机制的最终一致性
前面部分和上面基于事务型消息的队列,不同的是,第二阶段重试的地方,不再是消息中间件自身的重试逻辑了,而是单独的补偿任务机制。其实在大多数的逻辑中,第二阶段失败的概率比较小,所以单独独立补偿任务表出来,可以更加清晰,能够比较明确的直到当前多少任务是失败的。对应上图的E流程。
5、异步回调机制的引入
A应用调用B,在同步调用的返回结果中,B返回成功给到A,一般情况下,这时候就结束了,其实在99.99%的情况是没问题的,但是有时候为了确保100%,记住最起码在系统设计中100%,这时候B系统再回调A一下,告诉A,你调用我的逻辑,确实成功了。其实这个逻辑,非常类似TCP协议中的三次握手。
6、类似double check机制的确认机制
A在同步调用B,B返回成功了。这次调用结束了,但是A为了确保,在过一段时间,这个时间可以是几秒,也可以是每天定时处理,再调用B一次,查询一下之前的那次调用是否成功。例如A调用B更新订单状态,这时候成功了,延迟几秒后,A查询B,确认一下状态是否是自己刚刚期望的。
分布式事务的缺点
1、二阶段提交协议缺点
两阶段提交涉及到多个节点的网络通信,通信时间如果过长,事务的相对时间也就会过长,那么锁定资源的时间也就长了.在高并发的服务中,就会存在严重的性能瓶劲,也不一定可以保证一致性
2、消息队列
在高并发的环境中,我们一般会采用消息队列来避免分布式事务的执行。
在使用消息队列时,我们需要做到可靠凭证的保存(分布式事务的消息),有如下几种方式:
以支付宝和余额宝为例进行说明.
支付宝完成扣钱的动作时,记录消息数据,将消息数据和业务数据存在同一个数据库实例中.(同一个库保证了一致性)
将支付宝完成扣钱的消息及时发送给余额宝,余额宝完成处理后返回成功消息,支付宝收到消息后,消除消息表中对应的消息记录,即完成本次扣钱操作.
//=========================================
MQ也可以在另一个线程中进行发送,发送成功后就删除,就算删除不成功也没问题,大不了多发了一个消息。
为了确保消息的安全性,可以在发送端保存消息,更改状态表示消息已经发送了,通过消费端的回复再确认消息已经消费成功了就更安全了(防止MQ的数据丢失)
当然确保消息一定发送出去也是要确保才行
https://blog.csdn.net/zxl315/article/details/53433707(分布式事务最终一致性常用方案)
https://blog.csdn.net/qq_27384769/article/details/79305402(分布式事务)
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐