这是江帅帅的第027篇文章
一般的事务,指的是本地事务,单机上的事务。事务提供了一种机制,能够将一组操作放在一个不可分割的、独立的执行单元中,其中所有的操作要么被完全执行,要么完全失败。也就是,当其中一个操作执行失败的时候,都会让整个事务回滚。
全局事务是全局事务管理来实现全局管理。
假设有一个事务管理器,多个资源管理器在工作,事务管理器主要控制全局事务,管理事务和协调参与的资源,协同资源的一致提交和回滚等;资源管理器就控制和管理资源。
这里涉及到两个协议:TX 协议和 XA 协议。
TX 协议:应用或应用服务器与事务管理器的接口。
XA 协议:全局事务管理器和资源事务管理器的接口。XA 协议是 X/Open 组织提出的分布式事务的规范,当下主流的关系型数据库产品都实现了 XA 接口,它是双向的系统接口,为事务管理器和 N 个资源管理器提供通信桥梁。
在分布式系统中,需要引入一个单点来对两台机器进行协调,因为它们无法达到一致的状态,也就是 XA 需要引入事务管理器。这时,全局管理器负责管理和协调的事务,就能跨越多个资源和进程。
事务的 ACID 特性,特指本地事务的特性。分布式事务是多个事务的组合,也基本能满足 ACID,其中一致性是强一致性,为了保证数据一致性或完整性。由于分布式系统规模不小,也会越来越复杂,当需要达成强一致性将要耗费的时间会更长。后来出现了 BASE 理论,采用最终一致性来代替强一致性。
另外,隔离性是一种严格意义上的隔离,串行执行的多个事务互不干扰,能够保证数据的安全性,但性能很低,隔离级别和数据库的性能是成反比的。数据库的隔离级别有四种:Read uncommitted(读未提交)、Read committed(读提交)、Repeatable read(重复度)、Serializable(序列化)。
原子性(Atomicity):事务是一个不能分割的执行单元,只有两种状态,要么全部执行成功,要么全部不执行。如果事务中的出现任何一个操作失败,整个事务就失败,将会被回滚到之前的状态。
一致性(Consistency):事务在操作前到操作后,数据的完整性保持一致没有被破环。
隔离性(Isolation):如果系统内存在多个事务,且并发执行,但他们的执行是相互独立且不会相互干扰,某个事务内部的操作和数据,其他事务不可干涉。
持久性(Durability):当一个事务完成后,处理好的结果也将在数据库永久保存下来,哪怕系统出现崩溃、宕机,在系统恢复且能重新被访问,一样能看到事务提交的结果。
简单理解,分布式事务是在分布式系统中的本地事务,指在多节点、多机器、多服务的环境中涉及的事务操作。
核心点,分布式事务主要是解决在分布式系统环境下,组合事务的一致性问题。
目前,主要结合消息中间件共同处理相关操作,MQ 能实现异步通信、解耦和并发缓冲等问题。因为 MQ 拥有高并发、高吞吐能力,又能缓冲消息、灵活调整消息的处理效率,这就可以提升系统的并发量。
常见实现方式有遵从 ACID 的强一致性方式和遵从 BASE 理论的最终一致性方式,分别如下:
1)两阶段提交协议
2)三阶段提交协议
3)基于消息的最终一致性
基于 XA 协议的两阶段提交协议(Two-phase Commit Protocol, 2PC)方法,主要是 XA 能分离两部分来看,全局事务管理器和资源事务管理器。它具有能协调多个资源的机制,在 TM(事务管理器) 和 RM(资源管理器) 之间采取两阶段提交的方案来解决一致性问题。
TM 充当协调者,它会根据所有参与的 RM 的操作结果,来判断和控制是否需要最终提交。这过程会先经过投票,然后提交两个阶段。
过程很简单,TM 向 RM 发起准备操作的请求,然后等 RM 的响应。当 RM 接收到请求之后,会去执行请求中的事务操作,注意,这里单个 RM 没那么快提交,只会先记录日志信息,然后发送 Yes/No 给 TM,表示成功/终止操作指令。当所有 RM 都发送 Yes 的时候,才进入最终提交阶段,等提交完成后,整个事务就结束了。
从上图可以看到,协调者下发请求事务操作,参与者将操作的结果返回协调者,根据所有参与者的最终反馈结果来判断是要提交呢?还是回滚呢?
1)满足了事务的 ACID 的特性;
2)在执行过程中,2PC是反伸缩模式的,所有参与的节点都是事务阻塞型的,当业务规模越来越大的时候,局限性会更明显。参与者会一直持有资源直到整个分布式事务结束;
3)容易出现单点故障问题,2PC 类似于集中式算法,万一 TM 发生故障,RM 会去等 TM 的消息,然后会导致整个系统都处于停滞状态。
4)还有可能出现数据不一致的问题,万一网络抖动,网络局部异常现象,就只有部分 RM 接收到提交请求并执行操作,其他未接到提交请求的 RM 就不会执行事务提交操作,很明显的数据不一致问题。
为了解决上面两阶段提交会遇到的同步阻塞、数据不一致问题,出现了三阶段提交协议(Three-phase commit protocol, 3PC),是一套改进方案,因为三阶段拥有超时机制和多了一个准备阶段。
超时机制很好理解,在 TM 和 RM 之间引入超时机制,如果在规定时间内没有收到来自其他节点的响应信息,那么就会根据当下的状态来执行提交或者回滚操作。
另外多出来的一个准备阶段,其实是 3PC 把 2PC 一分为二,简单看就是:可以提交、预备提交、执行提交三个阶段。用这种方式来保证在最后提交之前,各个 RM 节点的状态都是一致的。
主要来看下“预备提交”阶段。
分两种情况,RM 返回的是 Yes,还是 No,然后再决定是否进行预备提交的操作。
如果返回 Yes,那也就是说能够去提交,接着正常的往下走,提交就是了。大致流程是先发送预备提交请求,进入预备提交阶段;然后执行事务操作,在日志中记录相关信息;最后事务执行成功了,得到 ACK 响应反馈,开始进入等待最后的操作指令。
如果返回 No,说明没戏,直接执行中断事务的操作。大致流程是先发送中断请求;然后中断事务操作。
因为 2PC 和 3PC 都会去锁定资源,就会降低系统性能,而且也没解决数据不一致的问题。
那应该怎么办?回到我们在上面介绍的“什么是分布式事务?”,简单提过,实际上需要结合消息中间件来共同处理相关操作,通过消息、日志等方式异步执行,因为它们可以存储在本地文件、数据库或者 MQ 中,加上重试机制,就是基于分布式消息的最终一致性方式来实现分布式事务解决方案。
在分布式事务中,只有当所有的事务都成功了,整个业务流程才能跑通,分布式事务的一致性是实现分布式事务的关键点。
公众号:江帅帅(ID:NXJSS666)
CSDN 博客:江帅帅
长按二维码关注
愿一个热爱技术的灵魂,给你带来更多惊喜文章。
感谢你的阅读!