问题描述:在秒杀场景下,当我们在redis中扣减库存后需要去MySQL中更新库存状态,这时为了减轻数据库的压力一般会使用消息中间件,比如RocketMQ,将扣减库存的消息发送到broker,再由consumer以固定的速率去消费。但这里我们需要保证扣减redis库存以及订单入库等操作与发送扣减库存的消息到broker都能成功,否则就会出现:1.redis扣减库存,但消息发送失败导致数据库未扣减,或者:2.redis扣减失败,但消息发送成功的情况。
解决方案:使用RocketMQ的事务型消息。
过程:发送一条不可消费的半消息到broker,然后执行本地事务(扣减redis,订单入库等一系列操作),本地事务成功提交后,半消息才对consumer可见,这时消息才能被正常消费。