给予消息队列实现分布式事务

给予消息队列实现分布式事务数据库

场景:

订单系统产生订单,购物车系统减购物车中的商。服务器

实现思路 :

  1. 订单系统在消息队列上开启一个事务(没有建立订单)。
  2. 订单系统给消息服务器发送一个“半消息”,这个半消息不是说消息内容不完整,它包含的内容就是完整的消息内容,半消息和普通消息的惟一区别是,在事务提交以前,对于消费者来讲,这个消息是不可见的。
  3. 半消息发送成功后,订单系统就能够执行本地事务了,在订单库中建立一条订单记录,并提交订单库的数据库事务。
  4. 而后根据本地事务的执行结果决定提交或者回滚事务消息。若是订单建立成功,那就提交事务消息,购物车系统就能够消费到这条消息继续后续的流程。若是订单建立失败,那就回滚事务消息,购物车系统就不会收到这条消息。

橙色和绿色分别是两个事务。异步

问题:

步骤4事务提交失败;这时候订单系统本地事务已提交尔购物车系统没有收到消息,形成数据不一致。分布式

如何解決消息队列事务提交过程出现的异常:

kafka会直接抛出异经常使用户自行处理;.net

在RocketMQ中的事务实现中,增长了事务反查的机制来解决事务消息提交失败的问题 , RocketMQ的Broker没有收到提交或者回滚的请求,Broker会按期去producer上反查这个事务对应的本地事务的状态,而后根据反查结果决定提交或者回滚这个事务。blog

为了支持事务反查机制,咱们的业务代码须要实现一个反查本地事务状态的接口告知RocketMQ本地事务是成功仍是失败。接口

本例中的反查逻辑很简单只需根据消息中的订单ID,在订单库中查询订单是否存在便可。队列

能不能在订单建立完成后再向消息队列发送订单数据?这样不用考虑订单建立失败而发送消息的状况了

考虑这样一种状况:订单建立成功了,还没来得及发消息,这个节点忽然断电了。事务

还有一种状况订单建立成功,减购物车(后续操做)失败的话要写实物补偿把建立的订单删掉。get

能不能这样:

1.开启本地事务建立订单,2.发消息,3.根据发消息是否成功来决定提交仍是回滚本地事务。这样不须要事务消息也能解决这个场景的问题了?

若是本地事务提交失败已发送的消息没法撤回,会致使数据不一致。

小结

不管是消息队列事务仍是异步事务都遵循事务的四大特性:原子性,一致性,隔离性,持久性。

更多实现分布式事务的方法: https://blog.csdn.net/ityqing/article/details/102655827


**** 码字不易若是对你有帮助请给个关注****

**** 爱技术爱生活 QQ群: 894109590****

相关文章
相关标签/搜索