在网上了解了分布式事务的一些方案,请教了一位前辈,理解如下
他公司分布式事务采取的方案是用MQ,对RabbitMQ进行改造,封装了一个新的MQ
先设定一个场景,下面是前辈说的话
比如支付前,update 订单状态支付中,调用支付接口,支付接口发送MQ信息告知支付成功还是失败,这边儿MQ接受消息,同时更新支付状态
这样分布式事务的数据一致性就保证了
库存的话,MQ这边儿没成功,库存进行+1操作
我:
MQ接受消息,更新了支付状态,然后在准备减库存的时候,失败了,这时候重试了几遍,还是失败,那是进行补偿,还是进行人工介入
前辈:
看是怎么失败的,要是数据库直接 抛异常(这种情况是你们数据库有问题了吧一般都是),这种情况本来就没法下单成功,除了返回系统错误之外没啥办法,但是之前缓存的,比如redis 里面的数据要进行+1操作,因为之前你已经扣减了
要是业务层面的失败,比如库存已经没了,减不下去了,这种情况也不存在,第一层redis就拦截了
说实话,我真没遇到过扣库存失败 ,重试还失败的情况,这个MQ消费不掉会一直重试的
我:
就是所有操作,像支付,扣库存,这些都是通过MQ来交互的,有异常,MQ就会不断重试,保证业务的完整性,可以这样理解吗
前辈:
嗯,对,你系统的异常,MQ会重试
我:
那MQ的调用,是链式的吗?比如说支付前,update 订单状态支付中,调用支付接口,支付接口发送MQA,信息告知支付成功还是失败,这边儿MQ接受消息,同时更新支付状态,然后在MQA里,发送MQB,通知扣库存,这样链式调用MQ
前辈:
就是一条链
正常情况,数据库异常,就会重试,直到扣减成功为止。系统异常是 你自己可以去定义 比如说给自己 短信通知,但是这种情况,除非你们数据库挂了,否则也不会发生,那重试就是为了防一下 数据库 超时的情况之类的
我:
感觉刚才聊的,都可以通过重试来解决,那什么场景下需要人工介入?还有补偿呢?补偿适用的场景应该就是转帐这类,要求数据强一致性的场景吧
前辈:
我也没见有人工介入过,补偿就库存补偿,或者付款失败之类,最终一致就行,以最终状态为准
我们系统 是 这样的 先下单,扣库存,扣DB库存(重试3次),如果都失败了,订单都无法生成,提示用户系统错误,下单失败,支付是放在最后一步的