数据库操作和发送MQ消息如何保证事务性
  uoXnpLX20IFp 2023年11月12日 23 0

事件驱动(event driven)的系统设计,服务之间的交互大多数都是通过消息队列中间件,那么我们都会面临一个微服务之间数据一致性的问题。

假设如下场景:服务A在一个事务中包含数据库更新操作,然后发送消息给MQ通知服务B

一般做法就是将数据库的操作以及发送消息放到一个事务中。如果数据库操作或者发送消息失败,则回滚事务即可。如果事务提交成功,消息发出去了以后,服务B处理消息出现异常,则我们只需要在fix调问题以后retry message就能够保证数据最终一致性。(当然在发送消息之前我们会将这个消息存储下来,redis或者数据库都可以,之后再做housekeep删除)。 但是我们会面临这样一个问题,假如服务B需要拿到服务A数据库更新操作以后的数据状态,但是我们的数据库操作跟发送消息是在一个事务里面的,那就可能存在服务B已经在处理消息了,但是服务A这边的事务还未提交,那么服务B从数据库中拿到的数据状态还是原来的数据状态。 所以对于这个问题,个人觉得比较好的做法就是,发送消息不要放在数据库事务中,等到数据库提交事务以后,会有一个回调事件(ATER_COMMIT),然后在这个回调事件中发送消息即可。 image.png begin tx 开启本地事务 do work 执行业务操作 insert message 向同实例消息库插入消息 end tx 事务提交 send message 网络向 server 发送消息 reponse server 回应消息 delete message 如果 server 回复成功则删除消息 scan messages 补偿任务扫描未发送消息 send message 补偿任务补偿消息 delete messages 补偿任务删除补偿成功的消息 跟人觉得以上是一种比较好的解决方案,发送消息前回将消息存储下来,如果服务消费方出现异常,只需要retry即可。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

推荐阅读
uoXnpLX20IFp
最新推荐 更多