分布式事务
-
基于MQ的可靠事务消息
- 消息生成者发送消息
- MQ收到消息,将消息进行持久化,在存储中新增一条记录
- 返回ACK给生产者
- MQ push 消息给对应的消费者,然后等待消费者返回ACK
- 如果消息消费者在指定时间内成功返回ack,那么MQ认为消息消费成功,在存储中删除消息,即执行第6步;如果MQ在指定时间内没有收到ACK,则认为消息消费失败,会尝试重新push消息,重复执行4、5、6步骤
- MQ删除消息
- 生产者发送一个半消息
- broker接收到消息并持久化后响应ACK
- 执行本地事务,本地事务执行完成后根据事务执行的结果继续发送commit或者rollback消息
- 接收到rollback消息直接将消息剔除,接收到commit将消息发送给消费者
解决方案非常的简单,就是其内部实现会有一个定时任务,去轮训状态为
待发送
的消息,然后给producer发送check请求,而producer必须实现一个check监听器,监听器的内容通常就是去检查与之对应的本地事务是否成功(一般就是查询DB),如果成功了,则MQ会将消息设置为可发送
,否则就删除消息。 -
最大努力通知
-
本地消息表的可靠事务消息
-
TCC
如何保证幂等性
- token机制:服务器判断token是否存在redis中,存在表示第一次请求,然后删除token,继续执行业务。
- 防重表:把唯一索引插入去重表,再进行业务操作,且他们在同一个事务中。这个保证了重复请求时,因为去重表有唯一约束,导致请求失败,避免了幂等问题。
- 唯一ID:调用接口时,生成一个唯一id,redis将数据保存到集合中(去重),存在即处理过。
- 分布式锁:redis锁
- 状态机:如果业务上需要修改订单状态,例如订单状态有待支付,支付中,支付成功,支付失败。设计时最好只支持状态的单向改变