系统A调用系统B如何保证分布式事务
业内的操作好多都靠同步调用 + 异步扫表补偿来做
大家都知道rpc的调用有三态,明确返回成功,明确返回失败,中间态
系统A 创建红包 init 状态
同步调用 B系统扣款,扣款明确返回成功
系统A 修改红包状态为已支付paid
系统A 再调用 C系统把红包信息发给客户端展示
系统A 修改红包状态为已展示show
然后同时又有一个补偿任务去异步扫过去一段时间的红包表
对于init 状态的,尝试重试调系统B扣款
对于paid 状态的,尝试重试调系统C 使红包展示
由于需要不断重试,直到下游明确返回成功,当然也是需要下游保证幂等性的
(上面的这个还是比较简单的,只是举个例子,不是线上真实场景)
再举个例子:
比如下一个订单,一个订单下会有履约服务不断尝试去投放广告,比如每个广告计费10元,投放一个广告就会记录消耗金额
我们有一个订单表记录订单和金额,履约表记录已消耗的金额
我们怎么保证钱不会被发超呢?
由于分布式三态的存在,我们需要引入另一张表广告投放流水表
流水表记录了对应的订单id和下单用户id以及流水的状态
系统拿到一条需要投放的广告,先落一条init状态的流水
流水推进任务扫这些流水,发现当前钱还没花完,就把流水置为 DOING,资源已经ready随时可以投放,可以理解成是在途的金额
此时还需要事务的把增加履约表的投放金额,这样钱就不会被花超了
扫到流水是 DOING的,此时去调用rpc去投放广告,明确返回成功,就把流水置为 DONE
明确返回失败,就把流水置为 ROLLBACK, 并事务的把上面履约表已增加的金额回滚掉
投放广告的幂等key就是订单id + 流水id
有了上面2个例子,应该能够很好的理解本地消息表了,如果遇到跨系统调用又需要保证系统数据的准确性就可以用起来啦
说点什么
您将是第一位评论人!