分布式事物设计

一、下面方式有什么问题?

try{
    1、插入数据库
    2、发送消息到MQ(超时情况)
    3、提交数据库插入
}catch(){
    回滚插入数据库
}

问题:1:成功;2:超时

当发送MQ超时时,并不代表就是发送失败了,有可能发送成功了,response时超时,此时回滚,导致数据不一致!

二、分布式事物类别:

1、刚性分布式事物:强一致性,CAP中的CP模型,如XA

2、柔性分布式事物:最终一致性,CAP中的AP模型,如BASE理论

三:刚性分布式事物之2PC两阶段提交(XA规范标准实现)

1、发起prepare投票

2、所有预提交都通过后,发起commit操作

扫描二维码关注公众号,回复: 6390840 查看本文章

3、如果commit阶段出现宕机等异常导致失败的,服务重启后,根据XA recover再次进行commit补偿(发起了commit就不能再回滚,只能再次发起commit补偿提交)

缺点:同步阻塞模型,锁定数据库时间长,并发低,事物较多时更慢,不适合多事物和高并发场景。

四、柔性分布式事物之saga模型,采取补偿的方式

向前补偿:根据消息表,回滚已经执行过的事物(建议此种方式:前面的事物能执行完成,说明服务是没有问题的,回滚也能回滚成功)

向后补偿:重试未完成的事物(事物提交失败,重试也可能会失败,有可能是服务挂了,导致无法进行下去)

五:柔性分布式事物应用

基于RocketMQ:

1、发送mq prepare消息到mq,并确认发送成功

2、提交本地事物

3、如果本地事物执行成功,commit mq里的消息,失败则删除 mq里的prepare消息

4、mq未收到3中的commit或者rollback,回查业务方提供的接口,查询事物状态:成功、失败、进行中则等待。

基于本地消息表:

1、通过本地事物,A库写入业务数据和消息数据

2、监控A库消息表,从消息表读取消息,发送到mq

3、B业务消费mq,B库执行事物成功后也记录本地消息表

4、通过消息表发送执行成功mq消息,A服务接到B的成功消息后,修改A库消息表状态或删除消息

异步方式:消息至少要发送成功一次,业务方保证幂等性(全局唯一id或者分布式锁保证幂等)

猜你喜欢

转载自blog.csdn.net/shaolong1013/article/details/91397049