消息队列里的分布式事务?(仅代表第二代消息队列,rocketmq和kafka)
消息队列的事务是为了保持生产者的数据和消费者的数据一致,保证生产者执行了操作,然后发送的消息,消费者一定要收到消息;
**例子背景:**订单系统在数据库生成订单然后再发消息给购物车系统,让系统将订单里的商品从购物车里移除;
**问题分析:**要保证生产者和消费者的数据一致性,第一得保证生产者执行了本地操作后一定能发送消息,反之失败不能发送消息,第二保证mq必须能将消息提交给消费者。第二mq可以根据自己的重传和操作的幂等性保证,因此只需要着重考虑第一点。
**常规想法:**要保证一致性,那么用原子性保证,只需要让生产者执行操作和发送消息操作是原子操作便可以解决,因此有了以下想法:
-
开启本地事务;
-
执行本地操作,在数据库创建订单信息;
2.1 若本地事务执行成功则发送消息到mq,提交本地事务;
2.2 若失败则回滚;
该想法一个漏洞是,在2.1提交事务时宕机,导致消息队列事务没有提交成功,本地操作作废,但是消息已经提交到mq,mq发给了消费者,因此导致数据不一致;
消息队列实现原理图: