【Bug】MQ消息与事务提交

项目联调期间,遇到个bug,涉及MQ消息传递和事务提交时间问题,简单记录下。

背景

审核服务(审核创建项目),点击审核通过,后台代码会在提交事务前发送MQ消息(该消息由项目管理服务消费),发送成功后,审核通过的事务才会提交(存入数据库),该次审核记录的状态更新为审核通过。示意图如下:

 

项目管理服务消费申请创建项目通过的消息(上文所述MQ消息),创建对应项目名称项目。创建项目时,要求项目名未使用(已创建项目集合中无同名项目、没有审核中的申请创建同名项目流程),否则创建项目失败(报错:xxx项目名已存在)。示意图如下:

 

现状

预期:审核通过申请创建项目的流程,项目管理服务能够成功创建同名项目。

实际:审核通过申请创建项目的流程,项目管理服务创建同名项目失败(偶尔成功),提示项目名已存在。

分析

单用户操作,不存在并发问题,且已有项目集合中无同名项目。

审核服务用于判断“是否有审核中的创建同名项目的申请”的接口,业务实现正确。

原因:审核通过,发送MQ成功后,再进行数据库操作并提交事务。在提交事务前,项目管理服务已消费消息并发起项目名重复校验。此时对应流程还是审核中。

按常理分析,审核服务内部的事务处理速度,应该比项目管理服务接收消息&创建项目&调用审核服务校验项目名接口速度快,但是现实环境确实出现了该问题。

可能原因:

1. 项目部署环境All in one,都是在同一台机器上,包括MQ。网络延迟小。

2. 审核服务提交事务,数据库因数据量、业务逻辑、磁盘性能等等原因,导致耗时过长。

简单来说,按照原场景,在事务提交前,确实有个时间差。

解决:

临时方案 - 项目管理服务对于来自审核服务创建项目的请求,不判断是否有审核中的同名项目申请(由审核服务在申请发起时自行校验)

个人推荐 - 审核服务通过申请时,先提交数据库事务,可以根据业务设计,将申请流程置位中间状态(如审核通过(待确认创建成功))。再发送MQ消息,若MQ发送失败,重置之前那条审核流程的状态(改为审核通过创建失败,或者回滚为审核中)

反思

在强约束要求下,优先数据入库,再进行其他操作。

同时,实现功能前,需要考虑服务间时延、服务/组件不可用等情况。

原文地址:https://www.cnblogs.com/xieyifeng/p/9855219.html