一种分布式数据库系统中分布式事务的处理方法与流程

文档序号:20917097发布日期:2020-05-29 13:40阅读:450来源:国知局
一种分布式数据库系统中分布式事务的处理方法与流程

本发明涉及数据库技术领域,具体涉及一种分布式数据库系统中分布式事务的处理方法。



背景技术:

随着业务规模的不断增大,集中式数据库系统已经难以通过扩展来满足业务事务处理的性能需求。分布式数据库系统是构建在分布式集群上的数据库系统,能够通过将数据切分到多个节点上的方式实现事务处理性能的扩展。当一个事务处理涉及到多个节点时,会成为分布式事务。为了保证分布式事务的原子性、一致性、隔离性、持久性(acid),分布式数据库系统需要在节点之间通过多次网络交互进行必要的同步。然而目前数据在网络中传输速度相差本地处理速度十倍以上,成为了分布式事务时延过高的主要原因。

现有技术中,为保证分布式事务执行的正确性,通常采用严格两阶段封锁(stricttwo-phaselocking,简称s2pl)和两阶段提交(two-phasecommit,简称2pc)协议。严格两阶段封锁协议的执行流程:增长阶段,事务可以获取锁,但不能释放锁;收缩阶段,事务可以释放锁,但不能获取新锁,并且要求事务提交或中止之前不能释写锁;两阶段提交协议的执行流程:准备阶段,事务管理器节点请求各个资源管理器对是否提交该事务继续投票,资源管理器节点必须做出响应;执行阶段,事务管理器节点依据投票结果向各个资源管理器节点发送事务提交与否的最终决议,资源管理器节点执行这个决议并返回确认信息。

上述现有技术中,存在如下缺陷:两阶段提交协议的执行需要多次耗时的网络交互,期间锁被事务持续持有,这增加了事务之间冲突的可能性,降低了事务的吞吐量,特别是在高冲突的负载下,这种影响尤为显著;为了提升容错能力,分布式数据库通常为数据维护多个副本,副本之间的同步会进一步延长锁的持有时间,事务处理的性能严重衰退。



技术实现要素:

本发明的目的是为了克服分布式事务执行过程中持锁时间过长的影响而提出的一种分布式数据库系统中分布式事务的处理方法,该方法能够缩短分布式事务持锁时间,降低事务之间冲突的可能性,从而提升事务处理的性能。

实现本发明目的的具体技术方案是:

一种分布式数据库系统中分布式事务的处理方法,该方法包括以下具体步骤:

步骤1:事务数据访问

以读/写锁模式对记录加锁,检查最新更新该记录的事务是否为已经提交或已经中止,若所述事务为已经提交或已经中止,则继续执行事务,若所述事务不为已经提交或已经中止,则将该事务加入到当前事务的输出依赖集合,并将当前事务的输入依赖数加一;

步骤2:事务准备

事务以提前写/提前读模式对本事务的写集合与读集合中的记录加锁,检查当前事务的输入依赖数是否为零或状态为中止,若当前事务为零或状态为中止,继续执行当前事务,若当前事务不为零或状态为中止,则一直阻塞当前事务;

检查当前事务是否状态为中止或违反隔离性,若当前事务为中止状态或违反隔离性,则回复事务管理器反对提交的消息,若当前事务不为中止状态且不违反隔离性,则对当前事务写集合和读集合中的记录解锁并回复事务管理器同意提交的消息;

步骤3:事务提交

检查当前事务是否可以提交,若当前事务可以提交,则执行事务提交,将当前事务的所有输出依赖事务的输入依赖数减一,设置当前事务的状态为已提交,回复事务管理器确认提交的消息;

步骤4:事务回滚

若当前事务不可以提交,则执行事务回滚,以中止锁模式对当前事务写集合中的记录加锁,先回滚当前事务的输出依赖事务,再回滚当前事务,对当前事务写集合中的记录进行解锁,设置当前事务状态为中止,回复事务管理器确认中止的消息。

所述锁模式包括读即read、写即write、提前读即e-read、提前写即e-write及中止即abort,当前为e-write/e-read锁模式时,与任何锁模式兼容;当前为任意锁模式时,与abort锁模式兼容;当前为abort锁模式时,与read和write锁模式不兼容。

本发明的有益效果:

本发明提出的分布式数据库系统中分布式事务的处理方法,在两阶段提交协议准备阶段提前释放了锁资源,这有效地缩减了锁的持有时间,减少了事务之间的冲突率,提高了分布式事务的性能;通过维护事务的输入依赖、输出依赖信息,确定事务的提交和回滚的顺序,避免了异常的发生,保证了正确性。并且本发明的技术方案易于工程实现,能快速应用于现有系统中。

附图说明

图1为本发明实施例1的流程图;

图2为本发明实施例2涉及的事务数据访问示意图;

图3是本发明实施例2涉及的事务准备示意图;

图4是本发明实施例2涉及的事务提交示意图;

图5是本发明实施例2涉及的事务回滚示意图。

具体实施方式

结合以下具体实施例和附图,对本发明作进一步的详细说明。实施本发明的过程、条件、实验方法等,除以下专门提及的内容之外,均为本领域的普遍知识和公知常识,本发明没有特别限制内容。

实施例1

参阅图1,本实施例包括锁模式、数据访问、事务准备、事务提交及事务回滚,其中,所述锁模式用来实现在事务数据访问、提前释放锁以及事务回滚时对数据的保护,有读(read)、写(write)、提前读(e-read)、提前写(e-write)、中止(abort)五种,当前为e-write/e-read锁模式时,与任何锁模式兼容,当前为任意锁模式时,与中止(abort)锁兼容,当前为abort锁模式时,与读锁和写锁不兼容。

其中,所述数据访问步骤包括如下步骤:

步骤a1:事务以读/写模式对记录x进行加锁;

步骤a2:事务通过记录x上的utid,寻找到最近更新记录x的事务in_xact上下文,判断其状态state是否为committed/aborted,成立则流程结束;

步骤a3:将记录x加入事务的读记录集合rs/写记录集合ws,并判断事务是否存在于事务in_xact的输出依赖集合(outdepset),成立则流程结束;

步骤a4:将事务加入到事务in_xact的输出依赖集合outdepset中,并将事务的输入依赖事务数目(indepcount)加1,流程结束。

其中,所述事务准备步骤包括如下步骤:

步骤b1:将事务的状态state设置为preparing;

步骤b2:将事务写集合中记录的最近更新事务标识号(utid)更新为事务的标识号(id);

步骤b3:对事务写集合和读集合中的记录加e-write/e-read锁;

步骤b4:判断事务的输入依赖事务数目不等于0并且不被级联回滚,成立则阻塞事务,不成立则继续执行后续步骤;

步骤b5:判断事务的状态state是否为aborted或者违反隔离性,不成立则跳转至步骤b7;

步骤b6:向事务管理器回复vote_no,流程结束;

步骤b7:对事务写集合和读集合中的记录进行解锁;

步骤b8:向事务管理器回复vote_yes,将事务的状态state设置为prepared;流程结束。

其中,所述事务提交步骤包括如下步骤:

步骤c1:释放持有的所有锁,将事务的所有输出依赖事务的indepcount减1,如果某个输出依赖事务的indepcount为0,则唤醒该输出依赖事务;

步骤c2:将事务的状态state设为committed;

步骤c3:发送ack_committed给事务管理器,流程结束。

其中,所述事务回滚步骤包括如下步骤:

步骤d1:对事务写集合ws中的记录加abort锁,并将utid设为无效事务id;

步骤d2:唤醒事务所有的输出依赖事务,对它们递归地执行事务回滚步骤;

步骤d3:进行undo操作,恢复数据;

步骤d4:对事务写集合ws中记录进行解锁操作;

步骤d5:将事务的状态state设置为aborted,流程结束。

实施例2

本实施例使用的锁模式,共有读(read)、写(write)、提前读(e-read)、提前写(e-write)和中止(abort)五种锁模式。这里需要注意的是:当前为e-write/e-read锁模式时,与任何锁模式兼容,效果相当于无锁;当前为任意锁模式时,与中止(abort)锁兼容;当前为abort锁模式时,与读锁和写锁不兼容。锁相容性矩阵如下所示。

表1

本实施例中依赖关系的定义如下:假设有两个事务a和b,如果事务a访问到事务b写入的数据,则称事务b是事务a的输入依赖,事务a是事务b的输出依赖。

为了实现提交依赖,对于每一个事务t,在事务的上下文中要维护以下信息:事务的读元组集合ws和写元组集合rs;事务id;当前事务的输入依赖数目,indepcount;依赖于当前事务的事务集合,outdepset;事务状态state;条件变量condition,用于控制临界条件。同时,在每一个元组上,需要记录对应的最近更新这个元组的事务utid。

图2描述一个事务访问一个元组的示例。在该例子中,事务a写过一个数据表t中id为1的元组,将字段name内容由cc更新为aa,并且已经准备完毕,同时事务b写这个元组,它先以写(write)锁定这个元组,更新这个元组的name字段内容为bb,然后根据这个元组上保存的utid,找到事务a的上下文,判断它的事务状态state,如果这个事务还未提交且没有回滚,将该元组加入事务b的写记录集合ws。如果事务b不存在事务a的输出依赖集合outdepset,并且将事务b的输入依赖数目indepcount加1。

图3描述一个事务准备的示例。在该例子中,事务b收到prepare消息后,将事务状态设为preparing。对于所有的写集合,更新每一个元组上对应的utid,并把元组上的锁由写(write)锁改成提前释放的写锁(e-write)。然后事务b阻塞等待,直到提交依赖的输入依赖数目indepcount为0,或者事务被级联回滚。唤醒之后,事务管理器发送事务b对prepare消息的响应,即vote_yes,将事务状态设为prepared。

下面两个示例分别说明事务提交和事务回滚的情况:

图4描述一个事务提交的示例。在该例子中,事务a进行提交操作,在资源管理器收到commit消息后,释放所有持有的锁。事务a遍历输出依赖集合(outdepset),对于输出依赖集合(outdepset)中的事务b,其输入依赖事务数目(indepcount)减1,此时事务b的输入依赖数量为0,则唤醒事务b,以使得事务b结束阻塞等待。此时事务a提交,更改事务状态为committed,并向事务管理器发送确认消息。

图5描述一个事务回滚的示例。在该例子中,事务a进行回滚操作,将写元组集ws中的每一个元组的锁状态更新为abort,并更新元组上的utid为无效值。这样,由表1可知,后续对这个元组的读写操作都会被阻塞。对于事务a的输出依赖事务b,递归地调用回滚操作,即所有输出依赖事务回滚之后本事务再回滚。事务b将元组name字段内容恢复为更新之前的aa,移除所有锁后更新状态为aborted,然后事务a再进行对元组name字段内容恢复成cc,数据回到初始状态。之后事务a移除所有锁,事务a更新状态为aborted。

本发明的保护内容不局限于以上实施例。在不背离发明构思的精神和范围下,本领域技术人员能够想到的变化和优点都被包括在本发明中,并且以所附的权利要求书为保护范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1