一文看懂分布式事务

及时获取有趣有料的技术文章

本地事务

事务Transaction由一组SQL组成,具有四个ACID特性:

Atomicity:原子性,构成事务的一组SQL,要么全部生效,要么全不生效,不会出现部分生效的情况。Consistency:一致性,数据库经过事务操作后从一种状态转变为另一个状态。可以说原子性是从行为上描述,而一致性是从结果上描述。Isolation:隔离性,事务操作的数据对象相对于其他事务操作的数据对象相互隔离,互不影响。Durability:持久性,事务提交后,其结果就是永久性的,即使发生宕机(非磁盘损坏)。

事务实现

对于MySQL数据库(InnoDB存储引擎)而言,隔离性是通过不同粒度的锁机制来实现事务间的隔离。

原子性、一致性和持久性通过redolog重做日志和undolog回滚日志来保证的。

redolog:当数据库对数据做修改的时候,需要把数据页从磁盘读到bufferpool中,然后在bufferpool中进行修改。

那么这个时候bufferpool中的数据页就与磁盘上的数据页内容不一致,称bufferpool的数据页为dirtypage脏数据。

如果这个时候发生非正常的DB服务重启,那么这些数据还没在内存,并没有同步到磁盘文件中(注意,同步到磁盘文件是个随机IO),也就是会发生数据丢失。

如果这个时候,能够在有一个文件,当bufferpool中的datapage变更结束后,把相应修改记录记录到这个文件(注意,记录日志是顺序IO)。

那么当DB服务发生crash的情况,恢复DB的时候,也可以根据这个文件的记录内容,重新应用到磁盘文件,数据保持一致。

undolog:undo日志用于存放数据被修改前的值,如果修改出现异常,可以使用undo日志来实现回滚操作,保证事务的一致性。另外InnoDBMVCC事务特性也是基于undo日志实现的。

undo日志分为insertundolog(insert语句产生的日志,事务提交后直接删除)和updateundolog(delete和update语句产生的日志,由于该undolog可能提供MVVC机制使用,所以不能再事务提交时删除)。

问题引入

CAP理论

CAP原则又称CAP定理,指的是在一个分布式系统中的一致性(Consistency)、可用性(Availability)、分区容错性(Partitiontolerance)。

CAP原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。但由于在分布式系统中,分区容错性必然存在,所以只能在一致性和可用性妥协。

传统的DBMS,如MySQL其实CA组合,在主从架构下,读写分离的情况下,是牺牲一定的一致性的(主从延迟)。

Base理论:

baseavailable,基本可用,分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。softstate,软状态,允许系统中存在中间状态,这个状态不影响系统可用性。eventuallyconsistent,最终一致性,系统的中间状态经过短暂的时间后到达一致状态。

如何解决

场景举例

考虑这样一种业务场景,系统A调用系统B的退款服务进行退款,系统A更改内部退款状态,接着调用系统C的短信服务通知用户。

在这样的一个场景下,由于网络不可靠的必然存在,存在A、B、C三个系统之间一致性的问题。

本地表

针对上述场景,设计两张表:退款记录表和短信发送记录表以及相应的补偿Job。

具体实现过程:

新增退款记录表,状态为处理中。调用系统B的退款服务进行退款。更新退款记录状态为对应的状态(成功/失败)。如果退款成功,则新增短信发送记录,记录状态为待发送。调用系统C的短信服务,发送短信。更新短信发送记录为已发送。

退款补偿Job,查询退款记录表中处理中的记录,调用系统B的退款服务,退款成功处理:

新增短信发送记录,记录状态为待发送。调用系统C的短信服务,发送短信。更新短信发送记录为已发送。

短信通知补偿Job,查询短信发送记录中待发送的记录,调用系统C的短信服务:

调用系统C的短信服务,发送短信。更新短信发送记录为已发送。

注意:

系统B和系统C需要根据调用方传的uuid支持幂等。系统A、B、C会出现短暂的不一致,但最终一致。

事务消息

可以将其视为两阶段提交消息实现,以确保分布式系统中的最终一致性。事务性消息可确保本地事务的执行和消息的发送可以原子方式执行。

但是由于事务消息异步的特性,调用方拿不到消费方的处理结果,适用于不关心对方的返回结果/对方负责保证处理成功。

针对上述场景,增加两个事务消息的方式解决一致性问题,系统A通过发送事务消息的方式与系统B和系统C进行交互。

具体实现过程:

发送退款的事务消息。新增退款记录,状态为:处理中。Commit退款事务消息。

提供MQ事务callback:

退款callback查询:有退款记录且为处理中则Commit;其他则Rollback。发送短信callback查询:有退款记录且成功则Commit;其他则Rollback。

退款同步Job,查询退款记录表中处理中的记录,调用系统B的退款查询接口同步状态,其中退款成功处理:

发送短信的事务消息更新退款记录为成功Commit短信事务消息

相关理论

二阶段提交

二阶段提交是解决分布式事务问题的重要理论基础,但也存在着明显的问题:

阻塞问题,参与者将协议消息发送给协调器后,它将阻塞直到收到提交或回滚,只能依赖协调者的超时机制。协调者单点问题,如果协调者出现故障,则某些参与者将一直无法收到提交或回滚的消息。

为了解决二阶段提交出现的问题,又有了三阶段提交(Three-phase


转载请注明:http://www.aierlanlan.com/rzdk/2536.html