分布式事务
1、两阶段提交协议
分为两个阶段:一个准备阶段 ,一个提交阶段。基于两阶段协议,事务管理器能够最大限度地保证跨数据库操作的事务原子性,是分布式系统环境下最严格的事务实现方法。但是两阶段协议存在性能方面问题,难于进行水平伸缩,因为在提交事务过程中,事务管理器需要每个参与者进行准备和提交的操作协调,在准备阶段锁定资源,在提交阶段消费资源。由于参与者众多,锁定资源和消费资源之间的时间差被拉长,导致响应速度较慢,产生死锁或不确定结果的可能性较大。在互联网很少使用两阶段提交协议。
两阶段提交协议是阻塞协议,在极端情况下不能快速响应请求方,因此提出了三阶段提交协议,解决了两阶段提交协议的阻塞问题,但仍然需要事务管理器在参与者之间协调,才能完成一个分布式事务。
2、最大努力保证模式
这是一种非常通用的保证分布式一致性的模式,很多开发人员一直在使用,但是未认识到这是一种模式,最大努力保证模式适用于对一致性要求并不十分严格但是对性能要求较高的场景。
具体的实现方式是:在更新多个资源时,将多个资源的提交尽量延后到最后一刻处理,如果业务流程出现问题,则所有的资源更新都可以回滚,事务仍然保持一致。唯一可能出现问题的是在提交多个资源时发生了系统问题,比如网络问题等。但是这种情况是非常罕见的,一旦出现这种情况,就需要进行实时补偿,将已提交的事务进行回滚。 当然在使用这种模式时,我们要考虑每个资源的提交顺序。我们在生产实践中遇到的一种反模式,就是在数据库事务中嵌套远程调用,而且远程调用的是耗时任务,导致数据库事务被拉长,最后拖垮数据库。
3、事务补偿机制
在对性能要求很高的场景中,两阶段提交协议不是一种好方案,最大努力保证模式也会使多个分布式操作相互嵌套,有可能相互影响。这里我们给出事务补偿机制,其性能很高,并且能尽最大可能地保证事务的一致性。
在数据库分库分表后,如果涉及的多个更新操作在某一个数据库范围内完成,则可以使用数据库内的本地事务保证一致性。对于跨库的多个操作,可通过补偿和重试,使其在一定的时间窗口内完成操作,这样就可以实现事务的最终一致性,突破事务遇到问题就回滚的传统思路。 如果采用事务补偿机制,则在遇到问题时,需要记录遇到问题的环境、信息、步骤、状态等,后续通过重试机制使其达到最终一致性。