分布式事务几种方案
2PC 模式
是一种刚性事务,遵循ACID原则,强一致性。
数据库支持的 2PC【2 phase commit 二阶提交】,又叫做 XA Transactions。
基于 XA和JTA 规范的,Spring 官方推荐的分布式事物实现方案有: Atomikos Bitronix。
第一阶段:事务协调器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交。
第二阶段:事务协调器要求每个数据库提交数据。
柔性事务-TCC 事务补偿型方案
柔性事务,与刚性事务不同,柔性事务允许一定时间内,不同节点的数据不一致,但要求最终一致。
所谓 TCC 模式,就是需要有3个接口。
一阶段 调用 Try 业务逻辑接口。
二阶段 调用 Confirm 确认接口。
二阶段 如果出现异常,调用Cancel 回滚接口。
柔性事务-可靠消息+最终一致性方案(异步确保型)
防止消息丢失:
1、做好消息确认机制(pulisher,consumer【手动 ack】)。
2、每一个发送的消息都在数据库做好记录。定期将失败的消息再次发送一 遍。
本地消息表(异步确保)
基本思路就是:
消息生产方,需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一个事务里提交,也就是说他们要在一个数据库里面。然后消息会经过MQ发送到消息的消费方。如果消息发送失败,会进行重试发送。
消息消费方,需要处理这个消息,并完成自己的业务逻辑。此时如果本地事务处理成功,表明已经处理成功了,如果处理失败,那么就会重试执行。如果是业务上面的失败,可以给生产方发送一个业务补偿消息,通知生产方进行回滚等操作。
生产方和消费方定时扫描本地消息表,把还没处理完成的消息或者失败的消息再发送一遍。如果有靠谱的自动对账补账逻辑,这种方案还是非常实用的。
这种方案遵循BASE理论,采用的是最终一致性,笔者认为是这几种方案里面比较适合实际业务场景的,即不会出现像2PC那样复杂的实现(当调用链很长的时候,2PC的可用性是非常低的),也不会像TCC那样可能出现确认或者回滚不了的情况。
缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。