🔊使用seata时遇到调用第三方接口无法回滚问题处理思路
🔊业务场景
两个微服务模块 订单模块 资金模块
一个第三方接口 erp接口
下订单时需要先将某笔钱退回并且推送给erp,然后重新占用一笔新金额然后推送erp接口
📆 问题描述
整个接口加上了seata全局事务管理
当退erp接口成功后,重新占用时 金额发生不足,因为加了全局事务会将在订单模块的退回操作回滚,但推送erp接口属于第三方接口,并不会回滚 ;导致的结果是自己系统数据回滚正常但已经推送了一笔退回资金的操作给erp接口
📕希望结果
当占用失败时;不仅订单业务中的金额需要回滚;刚刚推送给erp的金额也需要重新生成一条相对应的取反操作 以此进行平帐
🖥️解决思路
前提条件 日志模块不受seata管理 订单及资金模块受seata管理
-
退回金额时生成一个回滚序列号rollbackNum 用return+订单编码+时间戳
-
推送erp接口时增加一个日志,日志记录传递参数及结果 日志中记录字段
回滚序列号returnNum,回退状态 returnState 0无需回滚 1待回滚 2回滚成功 3回滚失败,回退操作推送成功后记录日志状态为 0无需回滚
-
在占用操作方法上增加 try catch 如果出现错误,先调用日志服务将rollbackNum 关联的日志回滚状态returnState 修改为1待回滚
-
然后发送mq,传递rollbackNum (因为mq消息也不受seata管理),mq接受到消息后将rollbackNum 关联的日志中returnState 1待回滚 3回滚失败两种状态的日志进行回滚,
-
由于日志中记录了回退时推送erp的请求参数,回滚时只需要清楚规则 将请求参数进行转换即可
🧣最后的话
🖲要熟练掌握技巧,一定多多练习:纸上得来终觉浅,绝知此事要躬行。