社区投稿 | 谈谈分布式事务基础概念

1 前言数据库


知道数据库的同窗确定都知道事务的概念,事务指的是一系列数据库操做,它是保证数据库正确性的基本逻辑单元,拥有ACID四个特性:原子性、一致性、隔离性与持久性。在分布式数据库系统中,分布式事务继承了传统事务的定义,但也由于自身的分布式特性而有其独特特色。
网络


本文将由浅入深,先从介绍传统单机事务开始,而后继续介绍分布式事务的概念、特性以及经常使用的分布式事务协议,最后谈谈本身对分布式事务的一些想法。并发


但愿经过阅读本文,让你们对分布式事务有个基本的认知。app


2 事务的基本概念分布式


在谈分布式事务以前,咱们先来讲说传统的单机数据库中的事务概念吧,包括事务的定义以及事务的特性。
ide


2.1 事务的定义spa


常常听人说,学会数据库的增删改查,就可以解决业务系统中百分之六七十的问题了。这里说的增删改查,对应的就是数据库的数据存取操做,这些操做对于数据库来讲,就是事务了。
日志


关于事务,先来讲说概念性的东西:咱们将对数据库的单个或多个操做序列的执行定义为事务,这些操做要么全作,要么全不作,是一个不可分割的工做单位。举个例子,下面这两种组成状况都叫作事务:code


  • 由单个操做序列(一条SQL语句)组成的事务orm

select * from test;


  • 由多个操做序列(SQL语句)组成的事务

select * from test where id = 1;
update test(id, name) set name = 'john' where id = 1;


固然,若是咱们没有显式声明事务的话,数据库则会给咱们自动地划分事务,对于MySQL来讲,没有显式声明事务,则一条SQL语句就是一个事务,执行完便会自动提交。


一个事务由开始标识(begin_transaction)、数据库操做和结束标识(commit或rollback)三部分组成。以下图所示:


(事务的基本模型)


关于上图的相关说明以下:

  • 事务开始:begin_transaction,说明事务的开始;

  • 数据库上的操做:表现为一条或多条SQL语句;

  • 事务提交:commit_transaction,提交事务操做,操做生效;

  • 事务回滚:rollback_transaction,事务取消,操做废弃。


2.2 事务的特性



事务是对数据库的一系列操做,是保证数据库正确性的基本逻辑单元,这句话就决定了事务必须具有ACID四个特性,才能保证数据库的正确性。下面咱们简要说明下ACID四个特性的基本概念:


  • 原子性


事务的原子性主要体如今事务中包含的操做要么所有完成,要么所有放弃,不存在中间状态,即一部分操做成功,一部分操做失败的状态。


  • 一致性


事务的一致性是指事务的执行结果必须使数据库从一种一致性状态变化到另外一种一致性状态,而不会停留在某种中间状态上。也就是说不管事务执行前仍是执行后,数据库状态均为一致性状态,处于这种状态的数据库才被认为是正确的。因而可知,事务的一致性与原子性是密切相关的。


事务的一致性


  • 隔离性


当多个事务的操做交叉执行时,若不加控制,一个事务的操做及其所使用的数据可能会对其余事务形成影响。事务的隔离性是指:一个事务的执行既不能被其余事务所干扰,同时也不能干扰其余事务。具体来说,一个没有结束的事务在提交以前不容许将其结果暴露给其余事务,这是由于未提交的事务有可能在之后的执行中回滚,所以,当前结果不必定是最终结果,而是一个无效的数据,不容许其余事务使用这种无效数据。


  • 持久性


事务的持久性体如今当一个事物提交后,系统保证该事务的结果不会因之后的故障而丢失,也就是说,事务一旦提交,它对数据库的更改将是永久性的。


上述即为事务的四个特性,ACID这四条特性起到了保证事务操做的正确性、维护数据库的一致性及完整性的做用


3 分布式事务


讲完了事务的基本概念,咱们正式开始谈谈分布式事务。


分布式事务与单机事务同样都是由一组操做序列组成,不一样的是单机事务只是在单机上执行,而分布式事务则是在多台机器上执行。下面咱们将介绍分布式事务的定义、分布式事务的提交协议(2PC、3PC)以及我对分布式事务的一些见解。


3.1 分布式事务的定义


咱们都知道事务是由一系列操做序列组成,对于单机事务,全部的这些操做序列都是在单机上面执行的,


以下图所示:


(单机事务)


而对于分布式数据库系统,事务的一系列操做序列会被拆分为子操做序列,而后在多台机器上执行,以下图所示:


(分布式事务)


在分布式数据库中的事务即被称为分布式事务,也叫全局事务,被拆分为在各个机器上执行的子操做序列,称为子事务。


分布式事务一样具备ACID四个特性,可是由于分布式数据库的分布特性,使其又有一些不一样。例如,为了保证分布式事务的原子性,必须保证组成该全局事务的全部子事务要么所有提交,要么所有回滚,不容许出现有些场地上的子事务提交,而有些场地上的子事务回滚。


所以,在分布式事务执行的过程当中,要比单机事务复杂的多,由于分布式事务除了要保证各个子事务的ACID特性外,还须要对这些子事务进行协调,决定各个子事务的提交与回滚,以保证全局事务的ACID特性。另外,在分布式事务中,还涉及大量的网络通讯,须要考虑到网络的影响。


经过上文,相信你们应该对分布式事务有了一些概念上的了解,下面咱们将介绍分布式事务的提交协议。


3.2 分布式事务的提交协议



对于分布式事务来说,全局事务的正确执行依赖各个子事务的正确执行。只有当各个局部操做都正确执行后,全局事务才能够提交,当发生异常要回滚全局事务时,全部局部操做也应回滚。所以,全部子事务均正确提交是分布式事务提交的前提。为实现分布式事务的提交,广泛采用两阶段提交协议(2 Phase Commit),简称2PC协议。


咱们已经知道分布式事务在执行时会被分解为多个场地上的子事务来执行。为协调各个场地上的子事务的执行,咱们须要一个协调者,而各个子事务的具体执行,须要本地的参与者来完成。为进一步理解两阶段提交协议,咱们先了解下协调者与参与者这两个概念:


  • 协调者:协调各个子事务的执行,负责决定全部子事务的提交或回滚;

  • 参与者:负责各个子事务的提交与回滚,并向协调者提出子事务的提交或回滚意向。


协调者与参与者的关系以下图所示:


(协调者与参与者的关系)


协调者和每一个参与者均拥有一个本地日志文件,用来记录各自的执行过程。不管是协调者仍是参与者,他们在进行操做前都必须将该操做记录到相应的日志文件中,以用来进行事务故障恢复。


协调者能够向各个参与者发送命令,使各个参与者在协调者的领导下执行命令,各个参与者也能够将自身的命令执行状态以应答的形式反馈给协调者,由协调者收集并分析这些应答以决定下一步的操做。


  • 3.2.1 两阶段提交协议的基本思想


两阶段提交协议是为了实现分布式事务提交而采用的协议。其基本思想是把全局事务的提交分为以下两个阶段:


  • 决定阶段:由协调者向各个参与者发出“预提交”(Prepare)命令,而后等待应答,若全部的参与者返回“准备提交”(Ready)应答,则该事务知足提交条件。若是至少有一个子事务返回“准备废弃”(Abort)应答,则该事务不能提交;

  • 执行阶段:在事务具有提交条件的状况下,协调者向各个参与者发出“提交”(Commit)命令,各个参与者执行提交;不然,协调者向各个参与者发出“废弃”(Abort)命令,各个参与者执行回滚,放弃对数据库的修改。不管是“提交”仍是“废弃”,各参与者执行完毕后都须要向协调者返回“确认”(ACK)应答,通知协调者事务执行结束。


两阶段提交协议的基本思想能够用下图表示:


(两阶段提交协议示意图)


  • 3.2.2 两阶段提交协议的基本流程


说完了两阶段提交协议的基本思想,咱们来具体看看两阶段提交协议的基本流程。


两阶段提交协议的基本流程以下图所示:


(两阶段提交协议的基本流程)


关于上图的步骤说明以下:

  • 协调者在征求各参与者的意见以前,首先要在它的日志文件中写入一条“开始提交”(Begin_commit)的记录。而后,协调者向全部参与者发送“预提交”(Prepare)命令,此时协调者进入等待状态,等待收集各参与者的应答;

  • 各个参与者接收到“预提交”(Prepare)命令后,根据状况判断其是否已经准备好提交子事务。若能够提交,则在参与者日志文件中写入一条“准备提交”(Ready)的记录,并将“准备提交”(Ready)的应答发送给协调者,不然,在参与者的日志文件中写入一条“准备废弃”(Abort)的记录,并将“准备废弃”(Abort)的应答发送给协调者。发送应答后,参与者将进入等待状态,等待协调者所作出的最终决定;

  • 协调者收集各参与者发来的应答,判断是否存在某个参与者发来“准备废弃”的应答,若存在,则采起两阶段提交协议的“一票否决制”,在其日志文件中写入一条“决定废弃”(Abort)的记录,并发送“全局废弃”(Abort)命令给各个参与者,不然,在其日志中写入一条“决定提交”(Commit)的记录,向全部参与者发送“全局提交”(Commit)命令。此时,协调者再次进入等待状态,等待收集各参与者的确认信息;

  • 各个参与者接收到协调者发来的命令后,判断该命令类型,若为“全局提交”命令,则在其日志文件中写入一条“提交”(Commit)的记录,并对子事务实施提交,不然,参与者在其日志文件中写入一条“废弃”(Abort)的记录,并对子事务实施废弃。实施完毕后,各个参与者要向协调者发送确认信息(Ack);

  • 当协调者接收到全部参与者发送的确认信息后,在其日志文件中写入“事务结束”(End_transaction)记录,全局事务终止。


3.3 对分布式事务的一点思考



上文对分布式事务的基本概念及经常使用的分布式提交协议(2PC)进行了一些说明,下面谈谈我对分布式事务的一些见解。


关于两阶段提交协议,若参与者收到了协调者发送的“提交”命令时,说明其余参与者均已向协调者发送了“准备提交”的应答,则参与者能够提交其子事务,可是两阶段提交协议有一点不足,就是若是协调者故障或者网络故障,致使参与者不能及时收到协调者发送的“提交”命令时,那么参与者将处于等待状态,直到得到所须要的信息后才能够作出决定。


在故障恢复前,参与者的行为将始终停留不前,子事务所占用的系统资源也不能被释放,这时咱们称事务进入了阻塞状态,阻塞状态会下降系统的可靠性与可用性。


由于两阶段提交协议的上述缺点,因此三阶段提交协议(3PC)被提出,三阶段提交协议在必定程度上解决了两阶段提交协议中的阻塞问题,这是由于当协调者故障或是网络故障时,参与者长时间未收到协调者的命令,参与者能够经过启动恢复处理过程,没必要进入等待状态而能够独立的作出决定。


三阶段提交协议虽然能够在必定程度上解决两阶段提交协议中的阻塞问题,但由于流程逻辑复杂,代码编写难度过高,也很难用于实际应用。


同时,为了保证分布式数据库的正确性,除了须要分布式事务的提交协议,咱们还须要分布式事务的恢复策略,在发生故障的时候对事务进行恢复,在分布式数据库系统中,除了会出现单机数据库中的故障外,还会出现网络故障、参与者故障这些分布式数据库系统中特有的故障,针对每种故障发生的状况,都须要有特定的恢复策略,可见分布式事务的恢复更是一个复杂的问题。


从我的看来,我认为完美的实现分布式事务是一件颇具挑战的事情,这可能也是目前不少产品都明确表示不建议开启分布式事务的缘由吧


4 结语


本文主要讨论了数据库系统中事务相关的一些概念与知识,包括单机事务与分布式事务以及我的对于分布式事务的一些见解。


最后,本人能力有限,文中有不正确的地方还望你们可以指出,同时也但愿本文能对你们有所帮助。


参考资料


《分布式数据库系统》.于戈 申德荣.机械工业出版社.2016年1月第2版
相关文章
相关标签/搜索