基于mq的异步分布式事务方案

商城下单场景:下单->减库存->扣费
很容易想到利用mq来异步解决,先上一段伪代码

   try{
        在数据库生成订单操作
        发mq消息到下游
    }catch(Exception e){
       conn.rollback();
    }finally{
        conn.commit();
    }

这段程序的貌似是可以完成任务的。逻辑如下:
如果第一步生成订单操作失败了,就不会发消息。事务回滚。
如果发消息失败了,本地事务回滚。
如果第一步生成订单成功,发消息也成功,就提交本地事务,
下游成功,则整个事务成功,下游失败,自己重试。

那么问题在哪里呢?
问题1,mq有可能超时,但其实发成功了,按上边逻辑本地事务要回滚,这就破坏了数据完整性。
问题2,第一步生成订单没报错,第二步发消息也成功了,但是commit的时候失败了,这个时候,本地订单没创建,但是下游消息已经发出去了。

如何改进上边代码?
增加一个事务表(msgid,content,topic,status)
利用本地事务,在创建订单时,也新增事务表一条记录。此时不发消息。
同进程内有一单线程的线程池,不断查询事务表,查到事务记录,将事务记录,发送到mq中,传递给下游。
同时监听mq的回执,收到回执后删除本地事务表记录。
消费端要自己去重。
如果下游失败,记录错误日志,报警,人工介入。
部署多实例时,发送端也需要排重,避免重复提交到mq。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。