基于本地消息表实现最终一致性
实现
这个方案的主要思想是将分布式事务拆分为本地事务和消息事务两个部分,本地事务在本地数据库中进行提交或回滚,而消息事务则将消息写入消息中间件中,以实现消息的可靠投递和顺序性。
一般来说的做法是,在发送消息之前,先创建一条本地消息,并且保证写本地业务数据的操作和写本地消息记录的操作在同一个事务中。这样就能确保只要业务操作成功,本地消息一定可以写成功。
然后再基于本地消息,调用MQ发送远程消息。
消息发出去之后,等待消费者消费,在消费者端,接收到消息之后,做业务处理,处理成功后再修改本地消息表的状态。
这个过程中,可能有几个步骤都可能发生失败,那么如果失败了怎么办呢?
- 1、2如果失败,因为在同一个事务中,所以事务会回滚,3及以后的步骤都不会执行。数据是一致的。
- 3如果失败,那么就需要有一个定时任务,不断的扫描本地消息数据,对于未成功的消息进行重新投递。
- 4、5如果失败,则依靠消息的重投机制,不断地重试。
- 6、7如果失败,那么就相当于两个分布式系统中的业务数据已经一致了,但是本地消息表的状态还是错的。这种情况也可以借助定时任务继续重投消息,让下游幂等消费再重新更改消息状态,或者本系统也可以通过定时任务去查询下游系统的状态,如果已经成功了,则直接推进消息状态即可。
优缺点
优点:
- 可靠性高:基于本地消息表实现分布式事务,可以将消息的发送和本地事务的执行进行原子性的提交,从而保证了消息的可靠性。
- 可扩展性好:基于本地消息表实现分布式事务,可以将消息的发送和本地事务的执行分开处理,从而提高了系统的可扩展性。
- 适用范围广:基于本地消息表实现分布式事务,可以适用于多种不同的业务场景,可以满足不同业务场景下的需求
缺点:
- 实现复杂度高:基于本地消息表实现分布式事务,需要设计复杂的事务协议和消息发送机制,并且需要进行相应的异常处理和补偿操作,因此实现复杂度较高。
- 系统性能受限:基于本地消息表实现分布式事务,需要将消息写入本地消息表,并且需要定时扫描本地消息表进行消息发送,因此对系统性能有一定影响。
基于本地消息表实现最终一致性
http://lzhnet.top/2023/07/02/基于本地消息表实现最终一致性/