CN111736964B - 事务处理方法、装置、计算机设备及存储介质 - Google Patents

事务处理方法、装置、计算机设备及存储介质 Download PDF

Info

Publication number
CN111736964B
CN111736964B CN202010628597.XA CN202010628597A CN111736964B CN 111736964 B CN111736964 B CN 111736964B CN 202010628597 A CN202010628597 A CN 202010628597A CN 111736964 B CN111736964 B CN 111736964B
Authority
CN
China
Prior art keywords
transaction
data
read
concurrent
write
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Active
Application number
CN202010628597.XA
Other languages
English (en)
Other versions
CN111736964A (zh
Inventor
李海翔
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Tencent Technology Shenzhen Co Ltd
Original Assignee
Tencent Technology Shenzhen Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Tencent Technology Shenzhen Co Ltd filed Critical Tencent Technology Shenzhen Co Ltd
Priority to CN202010628597.XA priority Critical patent/CN111736964B/zh
Publication of CN111736964A publication Critical patent/CN111736964A/zh
Application granted granted Critical
Publication of CN111736964B publication Critical patent/CN111736964B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/46Multiprogramming arrangements
    • G06F9/466Transaction processing
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/21Design, administration or maintenance of databases
    • G06F16/217Database tuning
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/24Querying
    • G06F16/245Query processing
    • G06F16/2453Query optimisation
    • G06F16/24532Query optimisation of parallel queries
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/27Replication, distribution or synchronisation of data between databases or within a distributed database system; Distributed database system architectures therefor
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/46Multiprogramming arrangements
    • G06F9/52Program synchronisation; Mutual exclusion, e.g. by means of semaphores
    • G06F9/526Mutual exclusion algorithms

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Databases & Information Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Software Systems (AREA)
  • Data Mining & Analysis (AREA)
  • Computational Linguistics (AREA)
  • Computing Systems (AREA)
  • Information Retrieval, Db Structures And Fs Structures Therefor (AREA)

Abstract

本申请公开了一种事务处理方法、装置、计算机设备及存储介质,属于数据库技术领域。本申请通过对于涉及到范围查询的目标事务,根据其数据集合的过滤条件也即是范围查询的谓词条件,获取到目标事务的读写集合,从而确定出读写集合存在重叠的至少一个并发事务,对目标事务与至少一个并发事务进行异常识别以获取异常识别信息,在异常识别信息指示不存在数据异常的情况下提交目标事务,这种方式既不完全依赖于封锁技术也不完全依赖于依赖图技术,避免了限制数据库系统的并发度,能够提升数据库系统的事务处理效率,有利于数据库扩容。

Description

事务处理方法、装置、计算机设备及存储介质
技术领域
本申请涉及数据库技术领域,特别涉及一种事务处理方法、装置、计算机设备及存储介质。
背景技术
随着数据库技术的发展,在数据库系统中如何识别并规避数据异常成为了一个关键问题。目前有两种识别数据异常的方法,其一是利用封锁技术,依赖锁的互斥机制来避免数据异常,其二是利用依赖图技术,通过在并发事务构成的依赖图中确认是否存在环,如果存在环则需要打破环的存在从而消除潜在的数据异常。然而,封锁技术严重限制了数据库系统的并发度,导致事务处理效率低下,而依赖图技术又需要遍历每个并发事务以识别出环的存在,导致事务处理效率仍然不高。因此,亟需一种能够提升事务处理效率的事务处理方法。
发明内容
本申请实施例提供了一种事务处理方法、装置、计算机设备及存储介质,能够提升数据库系统的事务处理效率。该技术方案如下:
一方面,提供了一种事务处理方法,该方法包括:
根据目标事务所操作的数据集合的过滤条件,获取所述目标事务的读写集合,所述过滤条件用于表示所述目标事务指定的所述数据集合的查询范围;
根据所述目标事务的读写集合,确定与所述目标事务所操作的数据集合重叠的至少一个并发事务;
对所述目标事务与所述至少一个并发事务进行异常识别,得到所述目标事务与所述至少一个并发事务之间的异常识别信息;
响应于所述异常识别信息为不存在数据异常,将所述至少一个并发事务与所述目标事务的读写集合进行合并,提交所述目标事务。
一方面,提供了一种事务处理装置,该装置包括:
获取模块,用于根据目标事务所操作的数据集合的过滤条件,获取所述目标事务的读写集合,所述过滤条件用于表示所述目标事务指定的所述数据集合的查询范围;
第一确定模块,用于根据所述目标事务的读写集合,确定与所述目标事务所操作的数据集合重叠的至少一个并发事务;
识别模块,用于对所述目标事务与所述至少一个并发事务进行异常识别,得到所述目标事务与所述至少一个并发事务之间的异常识别信息;
提交模块,用于响应于所述异常识别信息为不存在数据异常,将所述至少一个并发事务与所述目标事务的读写集合进行合并,提交所述目标事务。
在一种可能实施方式中,所述识别模块包括:
识别子模块,用于对于所述至少一个并发事务中任一并发事务,对所述目标事务与所述任一并发事务进行异常识别,得到所述目标事务与所述任一并发事务之间的异常识别子信息;
确定子模块,用于响应于所述至少一个并发事务中包括异常识别子信息为存在数据异常的并发事务,将所述异常识别信息确定为存在数据异常;否则,将所述异常识别信息确定为不存在数据异常。
在一种可能实施方式中,所述识别子模块包括:
第一获取单元,用于根据所述目标事务与所述任一并发事务的读写集合,获取第一集合、第二集合以及第三集合,所述第一集合为所述目标事务的读集与所述任一并发事务的写集之间的交集,所述第二集合为所述目标事务的写集与所述任一并发事务的读集之间的交集,所述第三集合为所述目标事务的写集与所述任一并发事务的写集之间的交集;
第二获取单元,用于响应于所述第三集合不是空集,根据所述任一并发事务的提交情况获取所述异常识别子信息;
第三获取单元,用于响应于所述第三集合是空集且所述第一集合或者所述第二集合中至少一项不是空集,根据所述第一集合和所述第二集合获取所述异常识别子信息。
在一种可能实施方式中,所述识别子模块包括:
第一获取单元,用于根据所述目标事务与所述任一并发事务的读写集合,获取第一集合、第二集合、第三集合以及第四集合,所述第一集合为所述目标事务的读集与所述任一并发事务的写集之间的交集,所述第二集合为所述目标事务的写集与所述任一并发事务的读集之间的交集,所述第三集合为所述目标事务的写集与所述任一并发事务的写集之间的交集,所述第四集合为所述目标事务的读集与所述任一并发事务的读集之间的交集;
第二获取单元,用于响应于所述第三集合不是空集,根据所述任一并发事务的提交情况获取所述异常识别子信息;
第四获取单元,用于响应于所述第三集合是空集且所述第一集合、所述第二集合或者所述第三集合中至少一项不是空集,根据所述第一集合、所述第二集合和所述第四集合获取所述异常识别子信息。
在一种可能实施方式中,所述第二获取单元用于:
若所述任一并发事务未提交且所述目标事务的目标参数为一,将所述异常识别子信息获取为存在数据异常且数据异常类型为谓词脏写异常,所述目标参数用于表示所述目标事务的读写集合成分所对应的已提交事务数量;
若所述任一并发事务已提交且所述第一集合与所述第三集合之间的交集不是空集,将所述异常识别子信息获取为存在数据异常且数据异常类型为谓词丢失更新异常。
在一种可能实施方式中,所述第三获取单元包括:
第一更新子单元,用于根据所述第一集合和所述第二集合,更新所述任一并发事务与所述目标事务之间的动边交叉值和变量状态值,所述动边交叉值用于表示所述任一并发事务与所述目标事务在数据状态矩阵中操作的不同数据项之间的线段交叉情况,所述变量状态值用于表示所述任一并发事务与所述目标事务涉及操作到处于不同数据状态的变量情况;
第一获取子单元,用于响应于所述更新后的动边交叉值大于或等于二,将所述异常识别子信息获取为存在数据异常;否则,将所述异常识别子信息获取为不存在数据异常。
在一种可能实施方式中,所述第一更新子单元用于:
响应于所述第一集合不是空集,将动边交叉值更新为已有值加一所得的数值;响应于所述第一集合中存在数据状态不同的变量,将变量状态值更新为已有值加一所得的数值;
响应于所述第二集合不是空集,将动边交叉值更新为已有值加一所得的数值;响应于所述第二集合中存在数据状态不同的变量,将变量状态值更新为已有值加一所得的数值。
在一种可能实施方式中,所述第四获取单元包括:
第二更新子单元,用于根据所述第一集合、所述第二集合和所述第四集合,更新所述任一并发事务的布尔型以及所述目标事务的布尔型,所述布尔型用于表示对应事务所构成的动边在数据状态矩阵中的垂直位置关系且所述布尔型的初始值为假;
第二获取子单元,用于响应于更新后的所述目标事务的布尔型和更新后的所述任一并发事务的布尔型均为真,将所述异常识别子信息获取为存在数据异常;否则,将所述异常识别子信息获取为不存在数据异常。
在一种可能实施方式中,所述第二更新子单元用于:
响应于所述第一集合不是空集,对于所述第一集合中任一变量,若所述变量在所述目标事务的读集中的版本号大于或等于所述变量在所述任一并发事务的写集中的版本号,将所述目标事务的布尔型更新为真;否则,将所述任一并发事务的布尔型更新为真;
响应于所述第二集合不是空集,对于所述第二集合中任一变量,若所述变量在所述目标事务的写集中的版本号大于所述变量在所述任一并发事务的读集中的版本号,将所述目标事务的布尔型更新为真;否则,将所述任一并发事务的布尔型更新为真;
响应于所述第四集合不是空集,对于所述第四集合中任一变量,若所述变量在所述目标事务的读集中的版本号大于所述变量在所述任一并发事务的读集中的版本号,将所述目标事务的布尔型更新为真;若所述变量在所述目标事务的读集中的版本号小于所述变量在所述任一并发事务的读集中的版本号,将所述任一并发事务的布尔型更新为真。
在一种可能实施方式中,所述装置还包括:
第二确定模块,用于响应于所述异常识别信息为存在数据异常,根据数据异常类型以及数据库系统的隔离级别,确定所述目标事务的执行结果,所述执行结果用于表示提交所述目标事务或者回滚所述目标事务。
在一种可能实施方式中,所述获取模块用于:
响应于所述过滤条件所包括的变量被读取,将被读取的变量添加至所述目标事务的读集中;
响应于所述过滤条件所包括的变量被写入,将被写入的变量添加至所述目标事务的写集中。
一方面,提供了一种计算机设备,该计算机设备包括一个或多个处理器和一个或多个存储器,该一个或多个存储器中存储有至少一条程序代码,该至少一条程序代码由该一个或多个处理器加载并执行以实现如上述任一种可能实现方式的事务处理方法所执行的操作。
一方面,提供了一种存储介质,该存储介质中存储有至少一条程序代码,该至少一条程序代码由处理器加载并执行以实现如上述任一种可能实现方式的事务处理方法所执行的操作。
一方面,提供一种计算机程序产品或计算机程序,所述计算机程序产品或所述计算机程序包括一条或多条程序代码,可选地,所述一条或多条程序代码存储在计算机可读存储介质中。计算机设备的一个或多个处理器能够从计算机可读存储介质中读取所述一条或多条程序代码,所述一个或多个处理器执行所述一条或多条程序代码,使得计算机设备能够执行上述任一种可能实施方式的事务处理方法。
本申请实施例提供的技术方案带来的有益效果至少包括:
通过对于涉及到范围查询的目标事务,根据其数据集合的过滤条件也即是范围查询的谓词条件,获取到目标事务的读写集合,从而确定出读写集合存在重叠的至少一个并发事务,对目标事务与至少一个并发事务进行异常识别以获取异常识别信息,在异常识别信息指示不存在数据异常的情况下提交目标事务,这种方式能够针对涉及到范围查询的目标事务,全面检测出数据库系统内各种各样的谓词类数据异常,从而保证了数据状态的一致性,并且这种事务处理机制既不完全依赖于封锁技术也不完全依赖于依赖图技术,避免了限制数据库系统的并发度,能够提升数据库系统的事务处理效率。
附图说明
为了更清楚地说明本申请实施例中的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还能够根据这些附图获得其他的附图。
图1是本申请实施例提供的一种事务处理方法的实施环境示意图;
图2是本申请实施例提供的一种垂边的示意图;
图3是本申请实施例提供的一种天边的示意图;
图4是本申请实施例提供的一种读写斜边的示意图;
图5是本申请实施例提供的一种只读斜边的示意图;
图6是本申请实施例提供的一种一致性状态边的原理图;
图7是本申请实施例提供的一种静边的示意图;
图8是本申请实施例提供的一种事务处理方法流程图;
图9是本申请实施例提供的一种获取异常识别子信息的流程图;
图10是本申请实施例提供的一种获取异常识别子信息的流程图;
图11是本申请实施例提供的一种锯齿波异常的原理性示意图;
图12是本申请实施例提供的一种事务处理装置的结构示意图;
图13是本申请实施例提供的一种计算机设备的结构示意图。
具体实施方式
为使本申请的目的、技术方案和优点更加清楚,下面将结合附图对本申请实施方式作进一步地详细描述。
本申请中术语“第一”“第二”等字样用于对作用和功能基本相同的相同项或相似项进行区分,应理解,“第一”、“第二”、“第n”之间不具有逻辑或时序上的依赖关系,也不对数量和执行顺序进行限定。
本申请中术语“至少一个”是指一个或多个,“多个”的含义是指两个或两个以上,例如,多个第一位置是指两个或两个以上的第一位置。
在介绍本申请实施例之前,需要引入一些云技术领域内的基本概念:
云技术(Cloud Technology):是指在广域网或局域网内将硬件、软件、网络等系列资源统一起来,实现数据的计算、储存、处理和共享的一种托管技术,也即是基于云计算商业模式应用的网络技术、信息技术、整合技术、管理平台技术、应用技术等的总称,能够组成资源池,按需所用,灵活便利。云计算技术将变成云技术领域的重要支撑。技术网络系统的后台服务需要大量的计算、存储资源,如视频网站、图片类网站和更多的门户网站。伴随着互联网行业的高度发展和应用,将来每个物品都有可能存在自己的识别标志,都需要传输到后台系统进行逻辑处理,不同程度级别的数据将会分开处理,各类行业数据皆需要强大的系统后盾支撑,均能通过云计算来实现。
云存储(Cloud Storage):是在云计算概念上延伸和发展出来的一个新的概念,分布式云存储系统(以下简称存储系统)是指通过集群应用、网格技术以及分布存储文件系统等功能,将网络中大量各种不同类型的存储设备(存储设备也称之为存储节点)通过应用软件或应用接口集合起来协同工作,共同对外提供数据存储和业务访问功能的一个存储系统。
数据库(Database):简而言之可视为一种电子化的文件柜——存储电子文件的处所,用户能够对文件中的数据进行新增、查询、更新、删除等操作。所谓“数据库”是以一定方式储存在一起、能与多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合。
本申请实施例所涉及的数据库系统,可选地,该数据库系统为单机数据库系统、单机以事务为主的数据库系统、单机以分析型为主但需要事务处理能力的数据库系统,可选地,该数据库系统为NoSQL(Non-relational SQL,泛指非关系型数据库)体系,可选地,该数据库系统为分布式数据库系统、分布式大数据处理系统,对于分布式数据库系统而言,当不同变量分布存储在不同的物理节点上时,对应于数据状态一致性模型中存在两个及两个以上变量的情况,数据状态一致性模型以及相应的事务处理流程均将在后文的各个实施例中进行详细说明,这里不做赘述。
可选地,在数据库系统中包括至少一个节点设备,每个节点设备的数据库中存储有多个数据表,每个数据表用于存储一个或多个数据项(也称为变量版本)。可选地,节点设备的数据库为任一类型的分布式数据库,包括关系型数据库或者非关系型数据库中至少一项,例如SQL(Structured Query Language,结构化查询语言)数据库、NoSQL、NewSQL(泛指各种新式的可拓展/高性能数据库)等,在本申请实施例中对数据库的类型不作具体限定。
在一些实施例中,本申请实施例还应用于一种基于区块链技术的数据库系统(以下简称为“区块链系统”),上述区块链系统在本质上属于一种去中心化式的分布式数据库系统,采用共识算法保持区块链上不同节点设备所记载的账本数据一致,通过密码算法保证不同节点设备之间账本数据的加密传送以及不可篡改,通过脚本系统来拓展账本功能,通过网络路由来进行不同节点设备之间的相互连接。
在区块链系统中包括一条或多条区块链,区块链是一串使用密码学方法相关联产生的数据块,每一个数据块中包含了一批次网络交易的信息,用于验证其信息的有效性(防伪)和生成下一个区块。
区块链系统中节点设备之间组成点对点(Peer To Peer,P2P)网络,P2P协议是一个运行在传输控制协议(Transmission Control Protocol,TCP)协议之上的应用层协议。在区块链系统中,任一节点设备具备如下可选功能:1)路由,节点设备具有的基本功能,用于支持节点设备之间的通信;2)应用,用于部署在区块链中,根据实际业务需求而实现特定业务,记录实现功能相关的数据形成账本数据,在账本数据中携带数字签名以表示数据来源,将账本数据发送至区块链系统中的其他节点设备,供其他节点设备在验证账本数据来源以及完整性成功时,将账本数据添加至临时区块中,其中,应用实现的业务包括钱包、共享账本、智能合约等;3)区块链,包括一系列按照先后的时间顺序相互接续的区块,新区块一旦加入到区块链中就不会再被移除,区块中记录了区块链系统中节点设备提交的账本数据。
在一些实施例中,每个区块中包括本区块存储交易记录的哈希值(本区块的哈希值)以及前一区块的哈希值,各区块通过哈希值连接形成区块链,另,区块中还包括有区块生成时的时间戳等信息。
在介绍本申请实施例之前,由于数据库系统中事务并发控制的正确程度能够通过一致性和隔离性来描述,下面对一致性和隔离性进行解释说明:
一、隔离性
事务隔离级别通过能否规避某种数据异常而进行定义,可能涉及到的数据异常包括:1)脏读,指一个事务读取到了另一事务尚未提交的数据项;2)不可重复读,指一个事务对同一数据项重复读取两次却得到了不同的结果;3)幻读,指事务在操作过程中进行两次谓词查询(范围查询),第二次查询的结果包含了第一次查询的结果中未出现的数据项或者缺少了第一次查询的结果中出现的数据项。
基于能够解决上述三种数据异常,数据库国际标准ANSI(American NationalStandards Institute,美国国家标准学会)SQL提出四种隔离级别,以对上述三种已知的数据异常加以区分,目的是在允许某些数据异常存在的情况下提高事务处理效率。
这四种隔离级别分别包括:1)读未提交:允许如上三种数据异常发生;2)读已提交:不允许脏读发生;3)可重复读:不允许脏读、不可重复读发生;4)可串行化:如上三种数据异常均不能发生。ANSI SQL定义的四种隔离级别与数据异常之间的关系能够采用下表1进行直观展示:
表1
隔离级别 脏写 脏读 不可重复读 幻读
读未提交 不允许 允许 允许 允许
读已提交 不允许 不允许 允许 允许
可重复读 不允许 不允许 不允许 允许
可串行化 不允许 不允许 不允许 不允许
能够看出,这四种隔离级别均不允许脏写异常发生,脏写异常是指两个未提交事务修改了同一个数据项。在ANSI SQL制定标准时已知的数据异常种类不多,后续不断有新的数据异常被发现,除了上述几种数据异常之外,目前已知的数据异常还包括:丢失更新异常、读偏序异常、写偏序异常、串行并发现象(Serial-Concurrent-Phenomenon)异常、交叉现象(Cross-Phenomenon)异常等。
在ANSI SQL标准的基础上,Jim Grey等人重新定义了六种隔离级别,采用更多的异常和更多的层级对隔离级别进行定义,这六种隔离级别与对应数据异常之间的关系能够采用下表2进行直观展示:
表2
Figure GDA0002650580260000091
Figure GDA0002650580260000101
二、一致性
数据库的一致性定义为:在事务的操作下,数据库的数据状态从一个一致的状态变迁为另一个一致的状态。上述“一致的状态”是指满足数据库系统预先定义的一些规则的数据状态,比如,这些规则包括约束、级联、触发器以及三者之间任意的组合(属于数据的逻辑语义),写偏序异常违反的就是特定数据之间的约束,这里的约束属于用户语义所限定的数据的一致性。
对于整个数据库系统而言,一致性还包括一层系统级的含义,是指要想保证数据在数据库系统中保持一致,还要求数据库系统符合两个特性,一个是可串行性(Serializability),另一个是可恢复性(Recoverability)。可串行性也即是说上述在隔离性中所定义到的可串行化隔离级别,可串行性保证了数据不会被并发操作改坏,而可恢复性是指已经提交的事务未曾读过被回滚的事务写过的数据(指不会发生脏读异常),可恢复性保证了事务被回滚后数据回到之前的一致的状态,被回滚的事务不会对数据的一致性造成影响,数据库系统的一致性状态是可恢复的。
基于上述概念可知一致性和隔离性与数据异常是息息相关的,目前,在数据库系统中如何识别并规避数据异常是一个犹为关键的问题。数据库的并发访问控制算法即可用于提供ANSI SQL标准定义的隔离级别,但在不同的数据库系统中其实现技术各不相同。
例如,DB2、Informix等数据库系统的可串行化隔离级别都是使用封锁技术,依赖锁的互斥机制来避免数据异常的发生;在MySQL数据库系统中,也是使用封锁技术实现可串行化隔离级别,此外,还使用SI(Snapshot Isolation,快照隔离)技术实现可重复度和读已提交隔离级别;在PostgreSQL数据库系统中,使用SSI(Serializable SnapshotIsolation,可串行化快照隔离)技术实现可串行化隔离级别,使用SI技术实现可重复度和读已提交隔离级别。又例如,在Spanner分布式数据库系统中,使用Truetime(真实时间)机制实现线性可串行化(线性可串行化是指分布式系统下结合了分布式一致性和事务一致性的一种与隔离级别有关联的级别,本质上包括了可串行化);在CockroachDB分布式数据库系统中,使用因果一致性和类似SSI的技术实现了可串行化和因果一致的结合。但是,上述这些数据库系统的隔离级别层次不够丰富,导致数据库系统的灵活度和事务处理效率不够好。
在上述关于一致性和隔离性的基础上,在目前已知的、传统的数据异常中,有两类数据异常比较特殊,分别是幻读异常和谓词写偏序异常,这两类数据异常均与谓词相关,而“谓词”是指SQL语句中WHERE子句部分的条件表达式,通过上述条件表达式能够限定谓词即SQL语句操作的数据对象范围,因此谓词也能够视为SQL语句所操作的数据集合的过滤条件,通过这种谓词的限定,使得被操作的数据对象看起来并不像传统的“R1(X2)”这类操作方式那么明显,其中,R1(X2)表示事务T1读取了数据项X2,而即使谓词限定的过滤条件中仅包含X2一个数据项,在明确知道要操作X变量的第二个版本的情况下,仍然不能很好地预测到被读写的对象是哪个数据项。
也即是说,对于幻读异常和谓词写偏序异常来说,由于SQL语句中使用了谓词,谓词操作的数据集合并非是具体的、可知的一个或多个数据项,而是符合某个谓词表达式的一个或多个数据项,由于谓词表达式的不确定性而显得相对虚幻而不可预料,在传统的并发控制算法都是针对具体可知的数据项进行的,导致虚幻与真实之间存在一道沟壑,理解谓词类数据异常会变得更加困难。
此外,谓词类数据异常还夹杂了用户特定的语义,比如谓词写偏序异常,用于对一些数据项可能是潜在存在特定语义的,特定的语义使得数据项之间的约束可能会被打破(最终不符合过滤条件),导致引发数据不一致的情况,因此谓词类数据异常也需要被避免。
在一个示例中,假设一个谓词写偏序异常,其语义如下:目标事务对于并发事务基于同样的谓词进行查询操作,结果集为空,或者结果集有数据但满足某个约束条件(如一天工作时间总和小于8小时),与此同时,某个并发事务新增了一个数据项(如一个新工作任务,分配5小时时间),使得其满足前述目标事务的谓词语义,那么单个并发事务将会提交成功,但是,在一些普遍的情况下,并发事务最后的操作结果仍然是违反约束条件的(如两个并发事务新增了2个工作任务,分配各5小时,那么工作时间总和是10小时,大于了8小时的约束规定),因此为保持数据一致性,在数据库系统中需要精准识别出谓词类数据异常。
可选地,上述谓词写偏序异常的初始表定义如下:
Figure GDA0002650580260000121
在可串行化的隔离级别下,对上述谓词写偏序异常进行如下表3的测试:
表3
Figure GDA0002650580260000122
Figure GDA0002650580260000131
在传统的技术体系中,仅发现了两种已知的谓词类数据异常(也即上面提到的幻读和谓词写偏序),但是将谓词类数据异常与非谓词类数据异常夹杂定义,实际上对这两类具有本质区别的数据异常的认知角度不统一,导致对谓词类数据异常的理解难度大幅提升,因为谓词表达了一个未知的数据对象范围(也即数据集合),这与非谓词类异常表达的一个个具体的数据对象是完全不同的,因此针对不同类型的数据异常所构造的异常定义、隔离级别、异常识别算法难以有效统一。
有鉴于此,在本申请实施例中,提出了10种谓词类数据异常,并在这些数据异常内囊括了已知的非谓词类数据异常,使得谓词类数据异常作为传统的非谓词类数据异常的父集而存在,这样保证对数据异常的认知更加统一化、标准化,从而能够更好地识别并避免谓词类数据异常。进一步地,给出了在事务处理过程中对谓词类数据异常的识别算法,并针对各个谓词类数据异常提供了对应的隔离级别以及分布式隔离级别,以及其各自使用的并发访问控制算法,下面将进行详述。
图1是本申请实施例提供的一种事务处理方法的实施环境示意图。参见图1,本实施例能够应用于分布式数据库系统,可选地,该系统中包括网关服务器101、全局时间戳生成集群102、分布式存储集群103以及分布式协调系统104(例如ZooKeeper),可选地,在分布式存储集群103中包括数据节点设备和协调节点设备。
其中,网关服务器101用于接收外部的读写请求,并将读写请求对应的读写事务分发至分布式存储集群103,比如,用户在登录终端上的应用客户端之后,触发应用客户端生成读写请求,调用分布式数据库系统提供的API(Application Programming Interface,应用程序编程接口)将该读写请求发送至网关服务器101,比如,该API为MySQL API(一种关系型数据库系统提供的API)。
在一些实施例中,该网关服务器101与分布式存储集群103中的任一个数据节点设备或任一协调节点设备合并在同一个物理机上,也即是,让某个数据节点设备或协调节点设备充当网关服务器101。
全局时间戳生成集群102用于生成全局事务的全局提交时间戳(GlobalTimestamp,Gts),该全局事务又称为分布式事务,是指涉及到多个数据节点设备的事务,例如全局读事务涉及到对多个数据节点设备上存储数据的读取,又例如,全局写事务涉及到对多个数据节点设备上的数据写入。全局时间戳生成集群102在逻辑上能够视为一个单点,但在一些实施例中能够通过一主三从的架构来提供具有更高可用性的服务,采用集群的形式来实现该全局提交时间戳的生成,能够防止单点故障,也就规避了单点瓶颈问题。
可选地,全局提交时间戳是一个在分布式数据库系统中全局唯一且单调递增的时间戳标识,能够用于标志每个事务全局提交的顺序,以此来反映出事务之间在真实时间上的先后关系(事务的全序关系),可选地,全局提交时间戳采用物理时钟、逻辑时钟、混合物理时钟或者混合逻辑时钟(Hybrid Logical Clock,HLC)中至少一项,本申请实施例不对全局提交时间戳的类型进行具体限定。
在一个示例性场景中,全局提交时间戳采用混合物理时钟的方式生成,全局提交时间戳由八字节组成,其中,前44位为物理时间戳的取值(也即Unix时间戳,精确到毫秒),这样共计能够表示244个无符号整数,因此理论上一共能够表示约为
Figure GDA0002650580260000151
年的物理时间戳,其中,后20位为在某一毫秒内的单调递增计数,这样每毫秒有220个(约100万个)计数,基于上述数据结构,如果单机(任一数据节点设备)的事务吞吐量为10w/s,理论上能够支持包含1万个节点设备的分布式存储集群103,同时,全局提交时间戳的数量代表了系统理论上所能支持的总事务数,基于上述数据结构,理论上系统能够支持(244-1)*220个事务。这里仅仅是对一种全局提交时间戳的定义方法的示例性说明,根据业务需求的不同,能够对全局提交时间戳的位数进行扩展,以满足对更多的节点数、事务处理数的支持,本申请实施例不对全局提交时间戳的定义方法进行具体限定。
在一些实施例中,该全局时间戳生成集群102是物理独立的,或者,该全局时间戳生成集群102与分布式协调系统104(例如ZooKeeper)合并到一起。
可选地,分布式存储集群103包括数据节点设备和协调节点设备,每个协调节点设备对应于至少一个数据节点设备,数据节点设备与协调节点设备的划分是针对不同事务而言的,以某一全局事务为例,全局事务的发起节点能够称为协调节点设备,全局事务所涉及的其他节点设备称为数据节点设备,数据节点设备或协调节点设备的数量为一个或多个,本申请实施例不对分布式存储集群103中数据节点设备或协调节点设备的数量进行具体限定。由于本实施例所提供的分布式数据库系统中缺乏全局事务管理器,因此在该系统中能够采用XA(eXtended Architecture,X/Open组织分布式事务规范)/2PC(Two-PhaseCommit,二阶段提交)技术来支持跨节点的事务(全局事务),保证跨节点写操作时数据的原子性和一致性,此时,协调节点设备用于充当2PC算法中的协调者,而该协调节点设备所对应的各个数据节点设备用于充当2PC算法中的参与者。
可选地,每个数据节点设备或协调节点设备是单机设备,或者采用主备结构(也即为一主多备集群),如图1所示,以节点设备(数据节点设备或协调节点设备)为一主两备集群为例进行示意,每个节点设备中包括一个主机和两个备机,可选地,每个主机或备机都对应配置有代理(agent)设备,比如,代理设备与主机或备机是物理独立的,又比如,代理设备作为主机或备机上的一个代理模块,以节点设备1为例,节点设备1包括一个主数据库及代理设备(主database+agent,简称主DB+agent),此外还包括两备数据库及代理设备(备database+agent,简称备DB+agent)。
在一个示例性场景中,每个节点设备所对应的主机或备机的数据库实例集合称为一个SET(集合),例如,假设某一节点设备为单机设备,那么该节点设备的SET仅为该单机设备的数据库实例,假设某一节点设备为一主两备集群,那么该节点设备的SET为主机数据库实例以及两个备机数据库实例的集合,此时能够基于云数据库的强同步技术来保证主机的数据与备机的副本数据之间的一致性,可选地,通过对每个SET进行线性扩容,能够应付大数据场景下的业务处理需求,在一些金融业务场景下,全局事务通常是指跨SET的转账。
分布式协调系统104用于对网关服务器101、全局时间戳生成集群102或者分布式存储集群103中至少一项进行管理,可选地,技术人员通过终端上的调度器(scheduler)访问该分布式协调系统104,从而基于前端的调度器来控制后端的分布式协调系统104,实现对各个集群或服务器的管理。例如,技术人员通过调度器来控制ZooKeeper将某一个节点设备从分布式存储集群103中删除,也即是使得某一个节点设备失效。
上述图1仅是提供了一种轻量级的全局事务处理的架构图,是一种类分布式数据库系统。整个分布式数据库系统看作是共同维护一个逻辑上的大表,这个大表中存储的数据通过主键被打散到分布式存储集群103中的各个节点设备中,每个节点设备上存储的数据是独立于其他节点设备的,从而实现了节点设备对逻辑大表的水平切分。由于在上述系统中能够将各个数据库中各个数据表水平切分后进行分布式地存储,因此,这种系统也能够形象地称为具有“分库分表”的架构。
在上述分布式数据库系统中,已经基于XA/2PC算法实现了写操作时数据的原子性和一致性,而读操作的数据一致性问题,需要通过构造一个轻量的、去中心化的分布式事务处理机制来改善,从技术的角度来看,分布分表架构缺乏一个全局事务管理器,也就缺乏分布式事务处理能力,通过构造上述轻量的、去中心化的分布式事务处理机制,能够为分布式数据库系统提供水平扩展等能力,并且保证分布式数据库系统简单易推广、事务处理效率更高,必将对传统并发控制方式所设计的分布式数据库架构产生极大冲击,具体的分布式事务处理机制将在下个实施例中进行详述。
本申请实施例提供的事务处理方法,能够应用于上述采用了分库分表架构的分布式系统中,例如,该分布式系统为分布式事务型数据库系统或者分布式关系型数据库系统,此外,本申请实施例提供的事务处理方法也能够应用于一些单机数据库系统中,对于分布式系统而言,需要分布式事务处理能力,且为了提高事务处理效率以应对不同用户在不同场景的应用需求,还需要提供丰富灵活的隔离级别。该事务处理方法不管应用在分布式系统还是单机数据库系统,均能够更好地、更为统一地实现高效的数据异常识别,实现高效的可串行化隔离级别,并采用统一的思路构造出行为一致的并发访问控制算法,从而使得数据库系统能够灵活适用于多种业务场景。
在一些实施例中,上述网关服务器101、全局时间戳生成集群102、分布式存储集群103以及分布式协调系统104所构成的分布式数据库系统,能够视为一种向用户终端提供数据服务的服务器,可选地,该服务器是独立的物理服务器,或者,该服务器是多个物理服务器构成的服务器集群或者分布式系统,或者,该服务器是提供云服务、云数据库、云计算、云函数、云存储、网络服务、云通信、中间件服务、域名服务、安全服务、CDN(Content DeliveryNetwork,内容分发网络)以及大数据和人工智能平台等基础云计算服务的云服务器。可选地,上述用户终端是智能手机、平板电脑、笔记本电脑、台式计算机、智能音箱、智能手表等,但并不局限于此。终端以及服务器能够通过有线或无线通信方式进行直接或间接地连接,本申请在此不做限制。
在介绍本申请实施例之前,首先将对数据库系统中所涉及到的一些基本术语以及符号表示进行介绍:
事务:事务是数据库管理系统在执行操作的过程中的一个逻辑单位,由一个有限的数据库操作序列构成,是数据库系统操作的最小执行单位。
变量:事务是数据库关系系统中的一个数据单位,变量是数据库操作的作用者(或者说操作对象),可选地,一个变量包含若干变量版本(在后文中也简称为“版本”),每当事务对变量进行更新时,则会添加新的变量版本,在一个示例中,变量的各个变量版本以自然数作为版本号标识,版本号越大,则表示变量版本越新。
操作:一个数据库操作由操作类型、事务、变量版本三部分构成,可选地,操作类型包括读(R)和写(W)两种。例如,事务T对变量x进行更新,生成了变量x的新版本i,上述读操作则记为WT(xi);又比如,事务T读取变量x的版本i的值,上述写操作记为RT(xi)。
事务数据集合:数据集合是由若干个变量版本所构成的集合,且集合中每个变量至多仅包含一个版本,记为数据集合DS(T)={xi,yj,zk,...|x,y,z为变量,i,j,k为版本号}。
数据库系统中的每个事务拥有两个事务数据集合,分别为事务的写集和事务的读集,其含义为:写集DSW(T)用于存储事务T所写入的新的数据版本,读集DSR(T)用于存储事务T所读取的数据版本。
版本读取集合:版本读取集合是由若干个事务所构成的集合,表示读取某一变量版本的全部事务,记为版本读取集合TS(xi)={Ti,Tj,Tk,...|i,j,k为事务ID},版本读取集合中既能够包括已提交事务,也能够包括未提交事务,其中,事务ID也即是事务标识(Identification)。
本申请实施例所提供的事务处理方法,是在数据状态一致性模型(简称为“数据状态模型”)的基础上运行的,而本申请所提供的数据状态一致性模型是数据库事务处理技术范围内第一次、全面、系统地提出一个模型,该模型揭示了各种数据异常的本质,而且统一了各种数据异常的描述和表达,解释了数据异常和并发事务之间的关联关系,并且,还能够发现出更多新的、未知的数据异常,能够更好地保证数据库系统的一致性。
需要说明的是,在数据状态一致性模型中包括两重基本规则,其一,禁止谓词脏写数据异常,也即禁止并发写写同一个变量,比如采取锁的方式禁止写写冲突。其二,禁止谓词脏读数据异常,比如通过采取读已提交的规则禁止脏读异常发生,即保证所读取到的数据一定是已经提交后的数据。
在上述数据状态一致性模型中,将事务与事务操作的变量版本之间的关系绘制成图形表示,下面,将对数据状态一致性模型所涉及的几个图形概念进行定义:
1、结点:每个变量版本为一个结点,由于一个变量能够包括若干版本,在图形表示中同一变量的若干版本按照由旧至新的顺序呈纵向排列,也即是说,在图形表示中,同一变量的若干版本呈一纵列,并且位于顶端的版本最旧,位于底端的版本最新。
2、垂边:同一个变量的两个相邻版本之间所存在的垂直边,称为“垂边”。垂边表示同一变量中版本的变迁,更新操作(比如DML的UPDATE语句)能够造成数据状态的改变,从而生成一条垂边。图2是本申请实施例提供的一种垂边的示意图,如图2所示,t0时刻存在变量版本x0,在t1时刻事务T1将变量版本x0更新为变量版本x1,记为W(x1),在变量版本x0与变量版本x1之间的垂线段200即为一条“垂边”。
需要注意的是,垂边包含“从变量的某一版本更新至另一版本”的含义,因此对于任一个事务而言,其垂边上端连接的变量版本,应加入到当前事务的读集中(无论是否实际对该变量版本执行过读操作)。另外,版本更新只能由单个事务进行,不能由并发事务进行,这样能够禁止写写并发,从而避免发生谓词脏写数据异常。此外,垂边和垂边不能重合,垂边只能是两个相邻版本之间的边,从而能够避免发生谓词丢失更新数据异常。
3、斜边:两个不同变量的版本之间存在的边,称为“斜边”。斜边表示两个变量之间的一致性状态,斜边能够划分为写写斜边(又称为“WW斜边”或“天边”)、读写斜边(又称为“RW斜边”)、读读斜边(“RR斜边”或“只读斜边”),其含义分别为:
1)天边:同一个事务修改了两个或两个以上不同的变量,则这些变量在两两之间能够构成一条天边。换言之,在事务的写集中,任意两变量之间一定存在一条天边,天边的两端分别与两结点的上端相连。图3是本申请实施例提供的一种天边的示意图,如图3所示,t0时刻存在变量版本x0和变量版本y0,在t1时刻事务T1将变量版本x0更新为变量版本x1,将变量版本y0修改为变量版本y1,记为W(x1)和W(y1),在变量版本x1与变量版本y1的上顶点之间的连线300即为一条“天边”。
需要说明的是,在一些实施例中,如果一个事务仅修改了一个变量,那么该事务的垂边的终端点称为天点,天点是天边的一种特殊形式,相当于天边的两端点重合,以图2为例,由于事务T1仅修改了一个变量版本x0,其垂边的终端点为变量版本x1,因此图2中的变量版本x1就是一个天点。此外,一个垂边不能跨越天点而存在,如果某一垂边跨越天点,则意味着两个并发事务在同时写同一个变量,会造成写写冲突即产生谓词脏写数据异常,按照基本规则需要禁止谓词脏写数据异常,因此垂边不能跨越天点。
2)读写斜边:某个事务在任何两个不同的变量间,先后存在读、写操作,则该事务所读的变量版本和所写的变量版本之间构成一条读写斜边。读写斜边的读端与结点下端相连,写端与结点上端相连。图4是本申请实施例提供的一种读写斜边的示意图,如图4所示,t0时刻存在变量版本x0和变量版本y0,在t1时刻事务T1将变量版本x0更新为变量版本x1,并读取变量版本y0,记为W(x1)和R(y0),在变量版本y0的下顶点与变量版本x1的上顶点之间的连线400即为一条“读写斜边”。
3)只读斜边:同一个事务读取两个或两个以上不同的变量,则这些变量在两两之间构成一条只读斜边。换言之,在事务的读集中,任意两变量之间一定存在一条只读斜边。只读斜边的两端分别与两结点的下端相连,也即是说只有当变量版本已经处于提交状态时才能够被事务读取到,此时执行读已提交规则。图5是本申请实施例提供的一种只读斜边的示意图,如图5所示,t0时刻存在变量版本x0和变量版本y0,随后某一事务将变量版本x0更新为变量版本x1,在t1时刻事务T1分别读取变量版本x1和变量版本y0,记为R(x1)和R(y0),在变量版本y0的下顶点与变量版本x1的下顶点之间的虚线500即为一条“只读斜边”。
4、一致性状态边:
一致性状态边由一个或多个斜边或垂边首尾相连构成,用于描述多个变量之间的一致性状态。例如,图3中变量版本x0与变量版本x1之间构成的垂边、变量版本x1与变量版本y1之间构成的天边、变量版本y0与变量版本y1之间构成的垂边,这三条边共同构成一个一致性状态边;又比如,图4中变量版本x0与变量版本x1之间构成的垂边、变量版本y0与变量版本x1之间构成的读写斜边,这两条边共同构成一个一致性状态边;又比如,图5中变量版本y0与变量版本x1之间构成的只读斜边,该只读斜边独自构成一个一致性状态边。
一致性状态边可能涉及多个事务的垂边或天边,也即是说,处于一致性状态边上的结点之间保持数据一致性,但这些结点并不一定是单个事务操作的,有可能涉及到多个并发事务。例如,图5中变量版本x0与变量版本x1之间构成的垂边以及变量版本y0与变量版本x1之间构成的只读斜边能够共同构成一致性状态边,但垂边是由某一事务执行更新操作而生成的,而只读斜边是由另一事务执行读取操作而生成的,虽然两者对应于不同的事务,但能够共同构成一个一致性状态边。
在一些实施例中,垂边能够被一致性状态边忽略,因此垂边不会和其他斜边构成动边交叉(动边交叉意味着存在数据异常),但在一些特定情况下,垂边是一致性状态边的组成部分,此时垂边不能够被一致性状态边忽略。
在一个示例中,仍以图5为例,变量版本x0与变量版本x1之间构成的垂边作为一致性状态边中最外层的边能够被忽略,而变量版本y0与变量版本x1之间构成的只读斜边能够作为一致性状态边。
在另一个示例中,图6是本申请实施例提供的一种一致性状态边的原理图,请参考图6,事务T1读取变量版本z0并写入变量版本x1,记为“R(z0)W(x1)”,事务T2读取变量版本y0写入变量版本z1,记为“R(y0)W(z1)”,如600所示,变量版本x0与变量版本x1之间构成的垂边、变量版本z0与变量版本x1之间构成的RW斜边、变量版本z0与变量版本z1之间构成的垂边、变量版本y0与变量版本z1之间构成的RW斜边能够共同构成一致性状态边,这是由2个事务T1和T2构成的一致性状态边,其中变量版本x0与变量版本x1之间构成的垂边作为一致性状态边的最外层的边可省略,而变量版本z0与变量版本z1之间构成的垂边作为一致性状态边的内层的边不可省略,这是由于内层的垂边起着联系其他斜边的作用,因此有可能会和其他斜边构成动边交叉,这种情况下垂边不可省略。
按照事务提交与否,一致性状态边能够划分为两种,下面分别进行介绍:
1)静边:指静态一致性状态边,静边上的结点由已经提交的事务生成,已提交事务的相关点(某个变量的状态)之间的边,是一条或多条RR斜边构成的一致性状态边,也即称为静边。静边反映了历史时刻上数据状态发生变化后,各个变量版本之间的一致性关系,历史态数据一旦在事务提交后形成,只能被读取而不能被篡改,在读取历史态数据时,静边能够保证读取到的变量之间是处于相同一致性状态的。
图7是本申请实施例提供的一种静边的示意图,如图7所示,3个变量的初始状态分别为r11,r21,r31,随着时间的推移(图7中从上至下代表时间增长),不同事务修改了变量状态,变量状态发生变化,比如T1事务将r11修改为r12,此时r12、r21和r31之间的虚线构成一条静边701,T2事务将r21和r31分别修改为r22和r32,则此时r22、r32和r12之间的连线构成一条静边702,T3事务将r12和r32分别修改为r13和r33,则此时r13、r33和r22之间的虚线构成一条静边703。如果在介于t1和t2时刻中间的任一个时间点读取保持一致性的变量版本,由于r22、r32的修改尚未提交,因此此时保持一致性的只能是r12、r21和r31间的虚线静边701,因此读取到的变量版本为r12、r21和r31。
2)动边:指动态一致性状态边,动边是并发事务集合中的一部分事务共同读写变量而构成的边,在并发事务集合中至少有一个事务没有提交。动边至少由一个事务构成,也可由多个事务构成,多个并发事务合并后可构成一条动边(并发事务合并条件在将后文进行介绍,这里不做赘述)。动边反映出了并发事务对数据状态的影响。
静边和动边协同反映了时态数据库中全态数据(包括历史态数据和当前态数据)的获取方式和技术(历史态数据只可读),还反映了数据状态的形成方式和技术,也即是说,当前态数据和并发事务是否不存在数据异常使得某个事务能够提交。
5、并发事务:
在数据状态一致性模型中,可选地,每个已经完成的事务按逻辑时钟有序,即事务的提交时间戳全局有序。如图7中的时刻t0~t3采用逻辑时钟定序,旧时刻从t0开始,按t0、t1、t2、t3等顺序逐步增长。
在保证全局有序的情况下,并发事务是指并发执行的两个或两个以上的事务在事务执行期间涉及到对相同的数据项进行读写操作,以两事务为例进行说明,若两事务对相同的变量在同一段时间内进行了读写操作,则认为两事务并发执行,假设存在事务T1和事务T2,若两事务满足ts(T1)<tc(T2)且ts(T2)<tc(T1),并对相同的变量执行过读写操作,也即是说T1的事务开始时刻ts小于T2的事务提交时刻tc,且T2的事务开始时刻ts小于T1的事务提交时刻tc,且两者对相同的变量执行过读写操作,此时能够认为T1和T2互为并发事务。
在一些实施例中,上述事务开始时刻有2种不同的含义:一种是事务启动时刻,另一种是事务的第一个读操作或写操作开始的时刻,两种含义均能够作为判定并发事务的条件,本申请实施例不对事务开始时刻的具体含义进行限定。
在同一时间段内一系列并发事务能够构成一个并发事务集合TS,并发事务集合TS={T1,T2,…,Tn},其中n≥2,n个事务中每个事务在该并发事务集合中均至少存在一个与其并发的事务,也即是说每个事务至少在该并发事务集合中存在“两事务并发执行”的情况,TS中每个元素(即事务)至少能找到另一元素(即另一事务)与其满足两事务并发执行,并发事务集合也能够简称并发事务,一个并发事务集合中至少存在一条“动态一致性状态边”(即动边)。
而事务提交算法,在本质上来说,是用于验证目标事务与并发事务之间是否存在动边交叉情况,如果不存在动边交叉,则认为不存在数据异常,目标事务能够提交,否则,认为存在数据异常,需要根据数据库系统的隔离级别,判断当前产生的数据异常在当前的隔离级别下是否禁止发生,从而决定目标事务进入提交阶段还是进入回滚阶段。
6、动边交叉:
动边交叉的定义如下:若两个并发事务操作两个不同变量,且每个事务分别操作不同变量的不同状态,且两条动边在不同状态之间互相跨越,这种情况称为动边交叉。上述2个不同的变量,可选地,其含义指2个不同的物理变量,如x、y,或者x1、x2,可选地,其含义指2个不同的逻辑变量,比如{x}、{y1,z0},其中,{x}和{y1,z0}都是逻辑变量,代表若干个变量的组合。
从本质上来说,动边从图形上看是在一个矩阵图(数据状态矩阵)上事务的操作在不同变量版本之间的线段,从集合的角度看,就是事务的读集和写集。所以动边交叉本质是两个并发事务Ti和Tj之间的读写集合是否符合某种条件,对于动边交叉的检测,在本申请实施例中提供了两种检测方式,下面分别进行说明。
方式一:
在初始化过程中,将动边交叉值(Dynamic Line Intersection,DLI)的初始值置为0,将变量状态值(Variable State,VS)的初始值置为0。其中,该动边交叉值用于表示事务Ti与事务Tj在数据状态矩阵中操作的不同数据项之间的线段交叉情况,该变量状态值用于表示事务Ti与事务Tj涉及操作到处于不同数据状态的变量情况。
进一步地,若事务Ti的读集和事务Tj的写集存在交集且两者的交集不为空集,则令DLI=DLI++,也即将DLI置为已有值加一所得的数值(这种操作俗称为“DLI自增1”);如两者的交集中某个非空元素的数据状态不同,则令VS=VS++,也即将VS置为已有值加一所得的数值(VS自增1);
若事务Ti的写集和事务Tj的读集存在交集且两者的交集不为空集,则令DLI=DLI++,也即将DLI置为已有值加一所得的数值(DLI自增1);如两者的交集中某个非空元素的数据状态不同,则令VS=VS++,也即将VS置为已有值加一所得的数值(VS自增1);
在事务Ti的写集和事务Tj的写集不存在交集(或者说两者的交集为空集)的情况下,能够保证满足基本规则中禁止写写冲突发生的条件,也即禁止脏写数据异常,如果动边交叉值DLI大于或等于2,且VS大于或等于1,则认为存在动边交叉,也即存在数据异常。在满足动边交叉的判定条件的基础上,可选地,根据变量状态值VS判断数据异常类型,VS=1时数据异常类型是读异常,包括1个变量的不可重复读异常、2个变量的读偏序异常、3个及3个以上变量的台阶式异常,VS=2时数据异常类型是写异常,包括2个变量的写偏序异常、3个及3个以上的锯齿波式异常。
方式二:
在初始化过程中,为每个事务各自分配一个布尔型,称之为upper,并将upper值初始化为false。该布尔型表示的是事务所构成的动边在数据状态矩阵中的垂直位置关系,以任意两个并发事务Ti和Tj为例,若Ti.upper=true,则表明事务Ti在某变量上构成的动边相对另一事务Tj较新,也即是说,针对同一变量而言,事务Ti在该变量上操作了比事务Tj较新的变量版本。
进一步地,若事务Ti的读集和事务Tj的写集存在交集,则对于交集中的每一个变量x,若事务Ti读变量x的版本≥事务Tj写变量x的版本,比如事务Ti读取变量版本x2、事务Tj写入变量版本x1,则置Ti.upper=true,否则,若事务Ti读变量x的版本<事务Tj写变量x的版本,比如事务Ti读取变量版本x1、事务Tj写入变量版本x2,则置Tj.upper=true。该规则对Ti的写集和Tj的读集比较的情况,可对事务Ti以及事务Tj的upper值进行同理赋值。
若事务Ti的读集和事务Tj的读集存在交集,则对于交集中的每一个变量x,若事务Ti读变量x的版本>事务Tj读变量x的版本,比如事务Ti读取变量版本x2、事务Tj读取变量版本x1,则置Ti.upper=true;若事务Ti读变量x的版本<事务Tj读变量x的版本,比如事务Ti读取变量版本x1、事务Tj读取变量版本x2,则置Tj.upper=true;若事务Ti读变量x的版本=事务Tj读变量x的版本,比如事务Ti和事务Tj均读取了变量版本x1,则不做任何操作。
在事务Ti的写集和事务Tj的写集不存在交集(或者说二者的交集为空集)的情况下,能够保证满足基本规则中禁止写写冲突发生的条件,也即禁止脏写数据异常。在以上述规则中,分别对事务Ti的写集和事务Tj的读集进行比较、对事务Ti的读集和事务Tj的写集进行比较、对事务Ti的读集和事务Tj的读集进行比较之后,若如果Ti.upper=Tj.upper=true,则认为存在动边交叉,也即存在数据异常。
动边交叉即构成数据异常,分析如下:动边由某个事务构成,如果该事务能够提交成功则该事务形成的动边处于一致性状态,由于两条动边各自保持一个一致性状态边,而交叉意味着两条动边互相跨越了对方的一致性状态边,分别操作(读写)了不同状态的数据,因而必定存在数据异常,发生动边交叉的并发事务集合中至少其中一个事务需要回滚。所以,数据异常的产生原因在本质上是:并发事务操作了不处于同一数据状态下的数据,即造成数据异常。
在动边交叉中,至少有一条动边包含一个未提交事务,需要说明的是,已提交的事务也有可能属于并发事务。
在并发事务集合中,如果在2个相同的变量上存在至少2条动边,以2条动边为例,按照排列组合,每条边有RR斜边、RW斜边、WR斜边这三种可能(其中WW斜边被禁止写写冲突的基本规则所禁止,所以读和写组合四种可能中只能取三种),故一共有
Figure GDA0002650580260000251
9种组合。因是动边,每个操作对都是针对不同变量,比如,RW斜边针对变量X和Y,则展开式为“R1(X0)W1(Y1)”。而在一个组合对中,比如RW-RW组合,假设事务T1的第一个RW对包括变量X和Y,那么事务T2的第二个RW对则必须针对变量Y和X,这是因为要构成一条动边(而不是一条静边),所以一定要跨越不同数据对象的不同状态,则第一个RW对展开式为“R1(X0)W1(Y1)”的情况下,第二个RW对的展开式只能是“R2(Y0)W2(X1)”,所以RW-RW组合其完整的操作序列应为:R1(X0)R2(Y0)W1(Y1)W2(X1)。但注意操作序列不只是这么一种,在此仅以这一种为例进行说明,除此以外还包括多种操作序列能够构成动边交叉。
上面提到的9种组合中的WR-WR、WR-RR、WR-RW三种关系,其中第一个“WR”操作对的展开式为“W1(X1)R2(X1)”,在读已提交规则下,其展开式还可能为“W1(X1)C1 R2(X1)”表明写事务已经提交结束,所以该关系不可能和后续的任何一个组合(RR、RW、WR三种之一)中的某个事务成为同一个事务,所以这三种组合不可能构成动边交叉。
进一步分析,9种组合中的RW-RW、RR-RR、RW-RR、RW-WR、RR-WR、RR-RW关系,能够构成动边交叉。在发生动边交叉时,至少一条动边中的未提交事务需要回滚,从而可解决数据异常的产生原因,保证数据库系统中的数据状态一致性。
7、数据状态历史:
一个数据对象用X表示,X值的变化,即可构成一个历史序列,从变量的角度来说,变量版本的变迁构成一个历史序列。变量X的历史序列如下:
Data History=DH=X0 X1...Xi Xi+1...X
其中,Xi称为一个变量版本,0≤i≤m,m为变量X的最大版本号。
其中,X0是数据的初始版本,表明数据对象X存在,值为X0。
其中,Xi和Xi+1是相邻的变量版本,Xi称为Xi+1的before-image(前像)。
版本变迁是指当发生写操作,将变量版本Xi变迁为变量版本Xi+1。
一个读操作或写操作发生,必定在数据状态的历史序列上,有一个与其对应的before-image。
在一个示例中,以W1(X0-X1)为例,X0-X1表示事务T1中,before-image是X0,产生的新版本是X1;同一个事务的连续多次写,不构成多个变量版本,即before-image相同时不构成多个变量版本。
在一个示例中,以R2(X2)为例,表示事务T2中,before-image是X2。
8、数据状态矩阵:
水平方向:n个变量,从左至右水平排列,分别称为X、Y、Z……,或者用a1、a2、a3……表示。
垂直方向:单个变量的数据状态历史序列。
由水平方向和垂直方向构成的一个由n个数据、最多m个数据状态的数据版本,构成一个n*m的矩阵,称为数据状态矩阵。图7所示的静边图就是数据状态矩阵的一部分。
并发事务之间所构成的斜边,在形式上是数据状态矩阵中不同变量版本间的连线,也是该数据状态矩阵的一部分。并发事务中每个并发事务构成的动边,是一个动态的、尚待验证是否能够保持合法状态的一致性状态边,如果事务能够成功提交,则该动边合法,动边也变为了静边。
数据状态矩阵上有一组或多组并发事务正在操作变量版本,从而形成一条或多条动边。在某组并发事务中,如果只有一条动边,则该动边表示的事务必可提交,这是由于单个动边不违反一致性状态,即不跨越一致性状态边,也即没有动边交叉;如果有两条动边构成动边交叉,则至少有一条动边对应的事务需要回滚,以避免对另外一条动边构成的一致性数据状态造成动态破坏。
本质上来讲,数据状态矩阵是并发事务的操作和生命空间,历史的事务在这个空间中沉淀(动边转化为静边),有冲突或无冲突的并发事务在这个空间中发生(当前存在的动边)。
9、动边合并:
两个并发的事务,每个事务的一致性状态边(即动边)要么存在数据异常(动边交叉),要么能够合并(即不存在数据异常)。也即是说,如果两个并发事务存在动边交叉,那么一定存在数据异常,否则,这两个事务的动边一定能够合并。
针对两事务合并而言,能够划分为三个维度上的合并,即事务合并、变量合并以及数据状态合并,下面分别进行介绍:
1)事务合并:并发事务集合中,若事务T1(表示为{T1})和事务T2(表示为{T2})能够构成一条动边,则事务T1和事务T2可合并为一个逻辑事务(表示为{T1,T2}),事务T1和事务T2的合并是指分别将事务T1和事务T2的读写集合进行合并,意味着事务T1的读集和事务T2的读集合并,事务T1的写集和事务T2的写集合并。事务合并的一个重要条件是合并在一起的事务之间不存在动边交叉,如果两事务存在动边交叉那么将无法合并。动边合并,形式上是将并发事务之间合并为一个逻辑事务,实质上是将并发事务的读写集合分别进行合并。
2)变量合并:在事务合并的过程中,若合并后事务的读集中包含变量版本Xi和Yj,合并后写集中包含变量版本X(i+1)和Y(j+1),此时进一步地进行变量合并,能够将变量X和Y合并为一个逻辑变量{X,Y},即合并后事务的读集中包含变量版本{Xi,Yj},合并后事务的写集中包含变量版本{X(i+1),Y(j+1)}。
3)数据状态合并:若事务合并的过程中,涉及某个变量的多个状态,如Xi和X(i+1),则变量纵向合并时,变为{X(i,i+1)}。
动边合并定义:分别隶属于两个事务的每两条动边,如果不存在动边交叉,则两个事务合并为一个逻辑事务,遵循前述的事务合并规则;在事务合并后,两个事务的读集和写集遵循变量合并规则;但是对于同一个变量而言,不同变量版本即不同状态的数据版本之间不合并,即不进行数据状态合并。
在上述描述中,提供了数据状态一致性模型,满足上述各种约束条件的并发事务,也即是符合数据状态一致性模型。
基于上述数据状态一致性模型,基于读已提交规则,对数据异常进行如下定义:
1、异常点:
当某个操作(读、写、提交、回滚)发生,动边交叉形成,则异常形成,称为异常形成点,简称异常点。异常点的形成,包括下述两种类型。
1)读写操作级:当读或写操作发生时,异常即形成,此时称为读写操作级异常异常点,简称操作级异常点。
2)事务级:非操作级异常,且当事务提交或回滚时,异常即形成,此时称为事务级异常异常点,简称事务级异常点。
这两种不同类型的异常点所对应的异常,分别称为操作级异常和事务级异常。此外,这两种不同类型的异常点,还影响着事务的并发度,将在下述针对并发度的介绍中进行详述。
2、并发度:
两事务满足ts(T1)<tc(T2)且ts(T2)<tc(T1),则称为两事务并行,或并行事务。
在两事务并行的基础上,如果两事务操作过至少同一个数据对象,称为事务并发,或并发事务。
两个并发事务的读写集合的交集不为空集,获取共同操作的数据对象(实则是数据的某个版本对象),这些数据对象在每个事务中对应的第一个操作和最后一个操作构成一个区间,该区间称为冲突区,也称为第一异常区间。冲突区的上界(最大值点)到事务级异常点之间的区间,称为第二异常区间。
冲突区/第一异常区间异常形成,即形成操作级异常,操作级异常对应的事务生命周期短,与其他事务的并发度低。此种情况称为并发度一度,简称一度。这里的生命周期短,并非用户的事务语义导致该事务的生命周期短,而是在异常已经发生导致该事务面临被迫回滚的风险,因此造成了事务的生命周期短。
事务级异常对应的事务能够在第二异常区间继续存在(事务的生命期长),与其他事务的并发度高。此种情况称为并发度二度,简称二度。一度的并发度小于二度的并发度。
3、异常分类:
(3.1)按照数据异常涉及的变量个数,将数据异常划分为单变量异常和多变量异常。单变量异常是指只涉及1个变量的数据异常,多变量异常是指涉及2个及2个以上变量的数据异常。
(3.2)按照数据异常涉及的变量是否存储在同一个数据节点设备(也称为子节点)上,将数据异常划分为分布式异常和局部异常。
A、分布式异常:如果一个多变量异常涉及的所有变量不都在一个子节点上存储,该异常称为分布式异常,一个分布式异常一定是多变量异常,但一个多变量异常也可能发生在同一个子节点上(也即涉及的所有变量都在一个子节点上存储),此时多变量异常为局部异常。
B、局部异常:一个单变量异常,该异常又称为局部异常(单变量异常必定是局部异常)。而幻读异常特殊,虽涉及到多个变量,但是以谓词为单位,读取到的一批数据能够视为“一个”变量,而符合谓词被新加入的数据,是依附谓词的,因此幻读异常也属于局部异常。非分布式异常的数据异常,即是局部异常。
(3.3)按照目标事务的SQL语句中是否包含谓词表达式,将数据异常划分为谓词类数据异常和非谓词类数据异常,而非谓词类数据异常在本质上是作为谓词类数据异常的子集存在的。
谓词类数据异常定义:谓词类数据异常,是指在一个事务内部,其读写操作使用了同一个谓词进行相关的操作,且出现数据异常。
谓词类数据异常还能够进一步划分为:谓词脏写数据异常、幻读数据异常、谓词读偏序数据异常、谓词写偏序数据异常、谓词读写偏序数据异常、谓词锯齿波数据异常、谓词台阶式数据异常。
需要说明的是,谓词类数据异常和非谓词类数据异常差别在于,产生谓词类数据异常的事务内读写操作中带有同样的谓词,但是谓词锁定的数据范围却不相同,因而不同的读操作、写操作读取或写入了不同的数据项;但是,谓词锁定的是一个数据集合,这点和非谓词类数据异常在其传统的形式化中定义类似,他们之间的差异在于,非谓词类数据异常锁定的数据对象是明确的、且为单一对象;谓词类数据异常锁定的数据对象是不明确的、且为空集或单一对象或多个对象。
因此,谓词类数据异常和非谓词类数据异常之间的形式化定义在数据项上的差别如下。
A、非谓词类数据异常:Action[{a single variable}],action为r(读)、w(写)、c(提交)或a(回滚),{}标识一个集合,只是集合中只有一个数据对象作为元素,也即非谓词类数据异常所操作的数据集合中仅包含单个变量。
B、谓词类数据异常:Action[{element}],action为action为r(读)、w(写)、c(提交)或a(回滚),{element}标识一个集合,可选地,该集合中不包含任意数据对象元素(即没有任何一个元素,为空集),可选地,该集合中仅包含一个数据对象元素,可选地,该集合中包含多个数据对象元素。
因此,不管是非谓词类数据异常还是谓词类数据异常,采用集合的表示方式,本质上统一了二种类型的数据异常之间的差别。并且显然能够看出来,非谓词类数据异常仅仅是谓词类数据异常的一种特殊情况,当谓词类数据异常所操作的数据集合中仅包含一个数据对象元素时等效于非谓词类数据异常,因此非谓词类数据异常是作为谓词类数据异常的子集存在的。
能够看出,谓词限定了具体的数据项,只是这些数据项不像x、y那样具体可知,而是通过谓词表达式来指定数据项的过滤条件,但逻辑上一定存在一些具体的数据项被谓词包括,所以在本质上两种数据类型是一样的。因此通过将数据状态矩阵扩展为逻辑数据状态矩阵,即可迁移到谓词类数据异常的异常识别过程中,其中,逻辑数据状态矩阵内的点不是一个具体的数据项,而替换为一个逻辑对象,此逻辑对象就是一个数据集合。
4、数据异常类型:
按照上述数据状态一致性模型,在本申请实施例中定义了10种谓词类数据异常,分别包括谓词脏写数据异常、谓词脏读数据异常、谓词中间读数据异常、谓词不可重复读数据异常/幻读数据异常、谓词丢失更新数据异常、谓词读偏序数据异常、谓词台阶式数据异常、谓词读写偏序数据异常、谓词写偏序数据异常以及谓词锯齿波数据异常,下面进行详述。
1)谓词脏写数据异常(Predicate Dirty Write):
定义:操作序列形如w1[{x1 in P}]...w2[{x2 in P}]...的数据异常,谓词脏写数据异常表明至少有一个同名变量x的两个不同版本x1、x2在操作序列中存在,属于操作级异常。
在一些实施例中,对于两个写操作造成的数据集合,如果至少存在一个“同一个数据项”的不同版本,则在识别数据对象的时候,将立刻被识别为传统的脏写数据异常,此时已经不必再识别是否存在其他的数据异常了。因此,传统的脏写数据异常是谓词脏写数据异常的一个特例。
2)谓词脏读数据异常(Predicate Dirty Read):
定义:操作序列形如w1[{x1 in P}]...r2[{x1 in P}]...(a1 and c2)的数据异常,谓词脏读数据异常表明至少有一个同名变量x在两个事务所操作的数据集合中出现,属于事务级异常。
同理,传统的脏读数据异常是谓词脏读数据异常的一个特例。
其中,对任一事务Ti(i≥1)而言,ci是指提交事务Ti,ai是指回滚事务Ti,比如a1是指回滚事务T1,c2是指提交事务T2,后面将不做赘述。
3)谓词中间读数据异常(Predicate Intermediate Reads):
定义:操作序列形如w1({x1 in P})...r2({x1 in P})...w1({x2 in P})...(c1and c2)的数据异常,谓词中间读数据异常表明至少有一个同名变量x的两个不同版本x1、x2在操作序列中存在,属于事务级异常。
同理,传统的中间读数据异常是谓词中间读数据异常的一个特例。
4)谓词不可重复读数据异常/幻读数据异常(Predicate Fuzzy or PredicateNon-Repeatable Read or Predicate Phantom or Phantom):
定义:操作序列形如r1[{x0 in P}]...w2[{x1 in P}]...c2...r1[{x1 in P}]的数据异常,谓词不可重复读数据异常属于操作级异常。
可选地,谓词不可重复读数据异常也能够遵循幻读数据异常的定义:操作序列形如r1[{x not in P}]...w2[{x in P}]...c2...r1[{x in P}]的数据异常,即至少有一个变量x,不在第一个r1所操作的数据集合中,但出现再第二个r1所操作的数据集合中,属于操作级异常。
同理,传统的不可重复读数据异常是谓词不可重复读数据异常的一个特例。传统的幻读数据异常本质上应该称作是谓词幻读数据异常。
5)谓词丢失更新数据异常(Predicate Lost Update):
定义:操作序列形如r1[{x0 in P}]...w2[{x1 in P}]...c2...w1[{x2 in P}]orrc1[{x0 in P}]...w2[{x1 in P}]...c2...w1[{x2 in P}]的数据异常,谓词丢失更新数据异常表明至少有一个同名变量x的三个不同版本x0、x1、x2在操作序列中存在,属于操作级异常。
同理,传统的丢失更新数据异常是谓词丢失更新数据异常的一个特例。
6)谓词读偏序数据异常(Predicate Read Skew):
定义:操作序列形如r1[{x0 in P}]...w2[{x1 in P}]...w2[{y1 in P}]...c2...r1[{y1 in P}]的数据异常,谓词读偏序数据异常表明至少有两个不同名变量x、y的其中之一有两个不同版本如x0、x1在操作序列中存在,属于操作级异常。
同理,传统的读偏序数据异常是谓词读偏序数据异常的一个特例。
7)谓词台阶式数据异常(Predicate Step Read Skew):
定义:操作序列形如r1[{x0 in P}]...w2[{x1 in P}]...w2[{y1 in P}]...c2...w3[{y2 in P}]...w3[{z1 in P}]...c3...r1[{z1 in P}]的数据异常,谓词台阶式数据异常表明至少有三个或三个以上的不同名变量x、y、z的其中之二(对于三个以上变量则更多)有两个不同版本如x0、x1和y0、y1在操作序列中存在,属于操作级异常。
同理,台阶式数据异常是谓词台阶式数据异常的一个特例。
在上述操作序列中,“w2[y1 in P]...c2...w3[y2 in P]”视为一个台阶,该台阶模式,能够扩展或变换出任意数量的中间变量和中间事务。扩展形式至少包括两个事务写同一个变量且其中一个事务已经提交。
其中,谓词台阶式数据异常又称为谓词阶梯式数据异常,包括3个及3个以上的变量。
8)谓词读写偏序数据异常(Predicate Read-Write Skew):
定义:操作序列形如r1[{x0 in P}]...w2[{x1 in P}]...w2[{y1 in P}]...c2...w1[{y2 in P}]的数据异常,谓词读写偏序数据异常表明至少有两个不同名变量x、y有两个不同版本如x0、x1和y1、y2在操作序列中存在,属于操作级异常。
同理,读写偏序异常是谓词读写偏序异常的一个特例。
9)谓词写偏序数据异常(Predicate Write Skew):
定义:操作序列形如r1({x0 in P})...r2({y0 in P})...w1[{y1 in P}]...w2[{x1 in P}]...(c1 and c2 in either order)的数据异常,谓词写偏序数据异常属于事务级异常。在第二个事务提交时,谓词写偏序数据异常才发生。
可选地,谓词写偏序数据异常还存在另一种定义:操作序列形如r1({x0 inP})...r2({y0 in P})...w1[{y1 in P}]...c1...w2[{x1 in P}]的数据异常,在此种定义下谓词写偏序数据异常属于操作级异常。
对于谓词写偏序数据异常来说,只能通过回滚后提交的事务的方式进行消除此类异常。
10)谓词锯齿波数据异常(Predicate Sawtooth Write Skew):
定义:操作序列形如r1[{x0 in P}]...r2[{y0 in P}]...r3[{z0 in P}]...w1[{y1 in P}]...w2[{z1 in P}]...w3[{x1 in P}]的数据异常,谓词锯齿波数据异常属于操作级异常。
谓词锯齿波数据异常也能够扩展至任意多个变量,相当于扩展出0至任意数量的锯齿,其扩展方式类似于锯齿波异常。
可选地,扩展模式为Ri[{k0 in P}]Wi[{a1}]表示一个锯齿,可选地,扩展模式也能够变形为:Ri[{k0 in P}]W[{a1 in P}]Ri[{a1 in P}]。
从上述关于谓词类数据异常的定义能够看出,谓词类数据异常的形式化定义,操作的是数据集合不是一个具体的数据项,但这本质上和只操作个别数据项的非谓词类数据异常是一样的,都是操作一个逻辑对象。所以,谓词类数据异常和非谓词类数据异常之间,理应存在以下对应关系,如表4所示。
表4
Figure GDA0002650580260000331
Figure GDA0002650580260000341
在上述针对谓词类数据异常类型进行了详尽定义的基础上,本申请实施例中针对数据库系统定义了新的隔离级别,定义隔离级别遵循如下原则:按照并发度从高到低的过程,其数据的一致性从弱到强,允许发生的数据异常从最多变为没有,具体地,包括读写未提交、读写已提交、快照可重复读和可串行化四种隔离级别,这四种隔离级别与数据异常之间的关系如下表5所示。
表5
Figure GDA0002650580260000342
从上表5中能够看出,在新的4种隔离级别中,谓词不可重复读与幻读不再割裂,而是合并为一个;且谓词写偏序不再与写偏序割裂,同样合并为一个;这样在逻辑上能够把谓词类异常和非谓词类异常高度统一,下面分别对各个隔离级别的含义进行介绍。
1、读写未提交(Read/Write Uncommitted,RWU)级别:对于没有提交的事务的中间状态,可读也可写,可读使得谓词脏读异常可能发生,可写使得谓词脏写异常可能发生。此RWU隔离级别和传统的“读未提交”级别的不同之处在于,RWU隔离级别没有对并发写操作进行屏蔽。也即,传统的读未提交不允许谓词脏写异常发生,RWU隔离级别允许谓词脏写异常发生。
2、读写已提交(Read/Write Committed,RWC)级别:只有处于已提交状态的数据,才可读才可写,可读避免了谓词脏读异常,即不能读事务执行的过程中的数据状态,可写避免了谓词脏写异常,即不能写/覆盖事务执行的过程中的数据状态。此RWC隔离级别和RWU隔离级别的不同之处在于,RWC隔离级别禁止了并发的写操作。
3、快照可重复读历史(Snapshot Repeatable Read,SRR):快照可重复读历史基于历史上的任何一个时间点(该时间点至多是系统最新的时刻,但不能是未来的某一个时刻),可读取历史上已经提交的数据,且使用同一个快照进行多次读,保持所有的读操作从同一个静边一致性状态获取数据。
4、可串行化(Serializable,S):无一切数据异常发生。不管是实体数据对象上发生的异常,还是在抽象语义下发生的异常,都被禁止。S隔离级别是最高的数据一致性级别。
需要说明的是,Jim Grey等人在表2中定义的游标稳定(Cursor Stability)隔离级别,不在本申请实施例提供的隔离级别之外,因为该游标稳定级别是基于特定的实现不同隔离级别的封锁技术而定义的,把特定的实现技术融合在隔离级别理论中不适宜。本申请实施例提供的隔离级别体系完全是基于已知异常和并发度的关系进行定义,所允许的数据异常类型越多,则系统的并发度越高,但数据一致性的强度越低;所允许的数据异常类型越少,则系统的并发度越低,但数据一致性的强度越高。所以隔离级别的数据一致性强度具有如下关系:RWU<RWC<SRR<S。
在提供了上述针对数据异常的定义、动边交叉的定义以及隔离级别的定义的基础上,图8是本申请实施例提供的一种事务处理方法流程图。参见图8,该实施例应用于数据库系统中任一节点设备,对于单机数据库系统而言,该节点设备是单机设备,对于分布式数据库系统而言,该节点设备为协调节点设备或者数据节点设备,该实施例包括下述步骤:
801、节点设备根据目标事务所操作的数据集合的过滤条件,获取该目标事务的读写集合,该过滤条件用于表示该目标事务指定的该数据集合的查询范围。
可选地,该目标事务是全局事务或者局部事务,其中,该全局事务是指涉及到跨节点操作的事务,全局事务也称为分布式事务,而局部事务则是指仅涉及单个节点操作的事务,局部事务也称为本地事务,本申请实施例不对目标事务的类型进行具体限定。
在上述过程中,节点设备在开始执行目标事务时,将该目标事务的读集和写集初始化为空集,可选地,目标事务能够由终端发起,此时终端与节点设备建立用于处理目标事务的会话,终端向节点设备发送目标事务的执行请求,节点设备响应于目标事务的执行请求,开始执行该目标事务。在一些实施例中,如果终端与节点设备已经建立过一个会话,那么无需在两者之间建立新的会话,只需要复用当前已建立的会话即可。
在读写集合的初始化过程中,可选地,节点设备在数据库系统启动时,向操作系统申请一块内存空间,该内存空间用于维护至少一个事务的读写集合(包括读集和写集),当目标事务开始执行时,节点设备从该内存空间中申请一块内存,该内存用于管理该目标事务的读写集合(包括读集和写集),从而在节点设备上完成了目标事务的读写集合的创建,并且,将创建出的读集和写集均初始化为空集。
在对读写集合初始化完毕后,节点设备从目标事务的执行语句中确定该目标事务的过滤条件(也即SQL语句中WHERE子句的条件表达式,俗称为谓词表达式),响应于该过滤条件所包括的变量被读取,将被读取的变量添加至目标事务的读集中;响应于该过滤条件所包括的变量被写入,将被写入的变量添加至目标事务的写集中。这一点是与非谓词类数据异常的不同之处,但并非其本质上的不同之处,因为在前面分析中得到谓词类数据异常包括了非谓词类数据异常,这两种类型的数据异常能够高度统一(谓词类数据异常基于集合,非谓词类数据异常基于的某个变量视为集合的部分元素)。
例如,当某一事务T对谓词表达式所包括的某个变量x进行更新时,将变量x添加至事务T的写集中,并为变量x分配版本号。不同事务对同一个变量的写操作的版本号按整数递增。新发生的读操作也因此可获得变量的版本号。即数据库系统为每个变量维护一个递增的版本号。另外,节点设备响应于该目标事务对谓词表达式所包括的任一变量进行读取,所读取的数据是最新的且满足读已提交规则的数据。
目标事务的读集和写集随着事务操作的进行而实时维护。如发生读操作,则被读取的数据进入读集;如发生写操作,则被读取的数据进入写集。同一个事务写同一个变量版本多次则有多个不同的新版本,在写集中用最新的版本替代旧的变量版本,上述初始化过程及维护策略能够称为读写阶段事务读写集合的形成算法。
在本申请实施例中,读写阶段事务读写集合的形成算法并非基于某个具体的数据对象,而是把数据对象置于一个数据集合中,把一个个数据集合看作一个逻辑上的数据对象,在此逻辑对象上运用事务读写集合的形成算法。
802、节点设备根据该目标事务的读写集合,确定与该目标事务所操作的数据集合重叠的至少一个并发事务。
其中,该至少一个并发事务与该目标事务在事务执行期间涉及到对相同的数据项进行读写操作,因此该至少一个并发事务所操作的数据集合与该目标事务所操作的数据集合重叠,这里的重叠包括部分重叠和全部重叠,只要两者所操作的数据集合中存在相同的数据项,那么即认为存在重合,互为并发事务。
在上述读写集合的维护策略下,对于目标事务的每一个操作(该操作为读操作或者写操作),在该操作发生时,进入准备阶段,节点设备进入临界区,遍历目标事务的读集和写集,获取目标事务的至少一个并发事务(比如所有并发事务)的事务标识,并将该至少一个并发事务的事务标识存入到一个链表TS中。
在获取并发事务的过程中,内存中的每个数据项上都能够记载曾经读写过本数据项但尚未提交的事务的事务标识(简称为活跃事务标识),可选地,每个数据项上记载的活跃事务标识为一个、多个或者空。节点设备只需要获取读集和写集中各个数据项上所记载的各个活跃事务标识,即可得到该至少一个并发事务的事务标识。
在上述过程中,相当于在目标事务的每个操作发生时,开始做准备工作,进入目标事务的准备阶段,准备阶段用于为事务T是否能够提交做好事务并发访问控制异常验证前的准备工作,节点设备在临界区中找到至少一个并发事务的事务标识之后,退出临界区。
803、节点设备对该目标事务与该至少一个并发事务进行异常识别,得到该目标事务与该至少一个并发事务之间的异常识别信息。
其中,该异常识别信息用于表示该至少一个并发事务与该目标事务之间是否存在数据异常。
在上述过程中,对该至少一个并发事务中任一并发事务,节点设备对该目标事务与该任一并发事务进行异常识别,得到该目标事务与该任一并发事务之间的一个异常识别子信息,响应于该至少一个并发事务中包括异常识别子信息为存在数据异常的并发事务,将最终的异常识别信息确定为存在数据异常,否则,将最终的异常识别信息确定为不存在数据异常。由于节点设备利用检测动边交叉的原理来进行数据的一致性检测,因此其一致性检测算法也称为动边交叉与合并算法。
在目标事务的每个操作发生时,都需要执行获取至少一个并发事务的步骤,以及对各个并发事务执行动边交叉与合并算法,假设当前进入验证阶段的待判断的目标事务为T,目标事务T最开始是一个物理事务,在通过动边交叉与合并算法的检验之后,如果最终的异常识别信息为不存在数据异常,那么将会变成一个合并后的逻辑事务。
在验证阶段,提供两种不同的动边交叉与合并算法,第一种是基于各事务的动边交叉值DLI和变量状态值VS进行异常检测,第二种是基于各事务的布尔型upper进行异常检测。
在第一种异常检测方式中,节点设备需要为DLI以及VS配置初始值,比如将两者的初始值都配置为0,也即令DLI=0;VS=0。接着执行进入下述循环操作:从链表TS中取出第一个事务定为TL,对TL执行基于DLI和VS的异常检测方法,当存在动边交叉时,报告异常发生,将异常识别子信息获取为存在数据异常,退出循环,将最终的异常识别信息获取为存在数据异常,否则,当不存在动边交叉时,将TL与目标事务T进行动边合并,得到新的事务T-new,并将T-new赋值给目标事务T,从链表TS中取出第二个事务定为TL,执行下一次循环(判断新的T-new与新的TL之间是否存在动边交叉),重复执行上述操作直到链表为空,结束循环,如果循环结束时仍没有异常报告,将最终的异常识别信息获取为不存在数据异常。上述基于DLI和VS的异常检测方法将在下个实施例中进行详述,这里不做展开。
在第二种异常检测方式中,节点设备为每个事务各自分配一个布尔型,称之为upper,并在初始化过程中将各事务的upper值初始化为false。接着执行下述循环操作:从链表TS中取出第一个事务定为TL,对TL执行基于upper的异常检测方法,当存在动边交叉时,报告异常发生,将异常识别子信息获取为存在数据异常,退出循环,将最终的异常识别信息获取为存在数据异常,否则,当不存在动边交叉时,将TL与目标事务T进行动边合并,得到新的事务T-new,并将T-new赋值给目标事务T,从链表TS中取出第二个事务定为TL,执行下一次循环(判断新的T-new与新的TL之间是否存在动边交叉),重复执行上述操作直到链表为空,结束循环,如果循环结束时仍没有异常报告,将最终的异常识别信息获取为不存在数据异常。上述基于upper的异常检测方法将在下个实施例中进行详述,这里不做展开。
在一些实施例中,由于基于集合的谓词运算会把谓词表达式(也即过滤条件)所确定的数据项作为一个子集合加入到目标事务的读写集合中,如果初始的谓词表达式所操作的子集合为空集,也即没有任何数据对象被谓词表达式所选定时,此时没有任何数据对象被加入到目标事务的读写集合中。
在一个示例性场景中,例如在给定工作表(workhours)的操作中,如果谓词表达式没有索引到任何数据项,不会有具有的数据项被添加到目标事务的读写集合中,这时假设系统存在谓词写偏序异常,那么在利用动边交叉与合并算法进行判断的时候,由于读写集合中没有数据项,不能构成动边交叉,将会产生不存在数据异常的误判情况。针对上述情况,本申请实施例提供以下两种解决方式:
方式一、对目标事务的每个谓词设置一个逻辑对象,在读写集合的维护阶段中,将逻辑对象加入到读写集合中,用该逻辑对象(可以包括0到任意数量的数据项)作为数据状态矩阵中的一个状态点,当然在矩阵图中对应于一个圆圈点,如果该逻辑对象内有某个数据项被其他事务读过或写过,则依然可以按照事务画出一致性状态边,因此能够构成动边交叉,并按照动边交叉与合并算法进行判断。尤其是在无数据项的情况下,也能够通过构造一个逻辑对象而在数据状态矩阵中构造出一个实体的圆圈点,以便于后续进行动边交叉检验,识别出是否存在多变量的数据异常。
方式二、直接在谓词锁操作的数据对象上施加排他锁,此后对谓词范围内其他并发事务的操作均会被排他锁阻塞,可以直接避免谓词写偏序异常的发生。
804、节点设备响应于该异常识别信息为不存在数据异常,将该至少一个并发事务与该目标事务的读写集合进行合并,提交该目标事务。
在上述过程中,当目标事务是局部事务时,如果该异常识别信息为不存在数据异常,也即循环结束仍没有异常报告,则该目标事务能够直接提交,当目标事务是分布式事务时,此时该节点设备还需要向协调节点设备上报本节点设备的异常识别信息,由协调节点设备根据各个节点设备上报的异常识别信息,全局判断是否提交目标事务,如果所有节点设备上报的异常识别信息均为不存在数据异常,那么协调节点设备向各个节点设备下发相应的提交指令,节点设备在接收到提交指令后提交目标事务,对目标事务进行数据落盘,否则,只要存在任一节点设备上报的异常识别信息为存在数据异常,协调节点设备向各个节点设备下发相应的回滚指令,节点设备在接收到回滚指令后回滚目标事务。
本申请实施例提供的方法,通过对于涉及到范围查询的目标事务,根据其数据集合的过滤条件也即是范围查询的谓词条件,获取到目标事务的读写集合,从而确定出读写集合存在重叠的至少一个并发事务,对目标事务与至少一个并发事务进行异常识别以获取异常识别信息,在异常识别信息指示不存在数据异常的情况下提交目标事务,这种方式能够针对涉及到范围查询的目标事务,全面检测出数据库系统内各种各样的谓词类数据异常,从而保证了数据状态的一致性,并且这种事务处理机制既不完全依赖于封锁技术也不完全依赖于依赖图技术,避免了限制数据库系统的并发度,能够提升数据库系统的事务处理效率。
上述所有可选技术方案,能够采用任意结合形成本公开的可选实施例,在此不再一一赘述。
下面,将详细介绍面向集合的动边交叉与合并算法(Set Dynamic LineIntersection–Merge,SDLI-M),SDLI-M算法基于数据状态一致性模型进行数据异常识别,从而判断并发事务是否符合数据一致性,SDLI-M算法没有消除出带有谓词的幻读、谓词写偏序数据异常的解决方式,也即仅实现了可串行化(S)隔离级别。
SDLI-M算法中包括读写阶段的事务读写集形成算法、准备阶段算法以及一致性检验算法(动边交叉与合并算法),在一致性检验算法中,分别提供了基于DLI和VS的异常检测方法以及基于upper的异常检测方法,两种异常检测方法均可以达成针对数据异常的识别与上报,下面将分别进行说明。
1、读写阶段事务读写集形成算法
在目标事务开始执行时,初始化目标事务的读集和写集为空集。
对于谓词读操作来说,如果谓词(也即过滤条件)包括的变量被读取,则将被读取的变量全部加入到读集中;对于谓词写操作来说,如果谓词包括的变量被写入,则将被写入的变量全部加入到写集中。
例如,当目标事务对谓词包括的某个变量x进行更新时,将变量x添加至目标事务的写集中,为变量x分配版本号。不同事务对同一个变量的写操作的版本号按整数递增。新发生的读操作也因此可获得变量的版本号,即为每个变量维护一个递增的版本号。
目标事务的读集和写集随着事务操作的进行而实时维护。同一个事务写同一个变量版本多次则有多个不同新的版本,在写集中用最新的版本替代旧的变量版本。此外,在读取过程中所读取的数据,是最新的满足读已提交规则的数据。
在一些实施例中,由于基于集合的谓词运算会把谓词表达式(也即过滤条件)所确定的数据项作为一个子集合加入到目标事务的读写集合中,如果初始的谓词表达式所操作的子集合为空集,也即没有任何数据对象被谓词表达式所选定时,此时没有任何数据对象被加入到目标事务的读写集合中。
在一个示例性场景中,例如在给定工作表(workhours)的操作中,如果谓词表达式没有索引到任何数据项,不会有具有的数据项被添加到目标事务的读写集合中,这时假设系统存在谓词写偏序异常,那么在利用SDLI-M算法进行判断的时候,由于读写集合中没有数据项,不能构成动边交叉,将会产生不存在数据异常的误判情况。针对上述情况,本申请实施例提供以下两种解决方式:
方式一、对目标事务的每个谓词设置一个逻辑对象,在读写集合的维护阶段中,将逻辑对象加入到读写集合中,用该逻辑对象(可以包括0到任意数量的数据项)作为数据状态矩阵中的一个状态点,当然在矩阵图中对应于一个圆圈点,如果该逻辑对象内有某个数据项被其他事务读过或写过,则依然可以按照事务画出一致性状态边,因此能够构成动边交叉,并按照动边交叉与合并算法进行判断。尤其是在无数据项的情况下,也能够通过构造一个逻辑对象而在数据状态矩阵中构造出一个实体的圆圈点,以便于后续进行动边交叉检验,识别出是否存在多变量的数据异常。
方式二、直接在谓词锁操作的数据对象上施加排他锁,此后对谓词范围内其他并发事务的操作均会被排他锁阻塞,可以直接避免谓词写偏序异常的发生。
上述事务读写集形成算法与上述步骤801所介绍的读写阶段的步骤类似,这里不做赘述。
2、每个操作发生时,执行准备阶段算法
在目标事务T的每个操作(或读或写)发生时,进入准备阶段并开始做准备工作,准备阶段用于为目标事务T是否可提交做好事务并发访问控制异常验证前的准备工作。
在准备阶段中,节点设备进入临界区,遍历目标事务T的读集和写集,找出目标事务T的所有并发事务的事务标识,放入一个链表TS内进行存储,在找到后退出临界区。在内存中,每个数据项上存有曾经读写过本数据项但尚未提交的事务的事务标识。
上述准备阶段算法与上述步骤802所介绍的准备阶段的步骤类似,这里不做赘述。
3、每个操作发生时,执行一致性检验算法(也即动边交叉与合并算法)
对于目标事务的任一并发事务,节点设备对该目标事务与该任一并发事务进行异常识别,得到该目标事务与该任一并发事务之间的一个异常识别子信息,响应于该至少一个并发事务中包括异常识别子信息为存在数据异常的并发事务,将最终的异常识别信息确定为存在数据异常,否则,将最终的异常识别信息确定为不存在数据异常。
换言之,节点设备从链表TS中取出第一个事务定为TL,对TL执行动边交叉与合并算法,当存在动边交叉时,报告异常发生,将异常识别子信息获取为存在数据异常,退出循环,将最终的异常识别信息获取为存在数据异常,否则,当不存在动边交叉时,将TL与目标事务T进行动边合并,得到新的事务T-new,并将T-new赋值给目标事务T,从链表TS中取出第二个事务定为TL,执行下一次循环(判断新的T-new与新的TL之间是否存在动边交叉),重复执行上述操作直到链表为空,结束循环,如果循环结束时仍没有异常报告,将最终的异常识别信息获取为不存在数据异常。
在本申请实施例中,动边交叉与合并算法包括两种不同的类型,第一种是基于DLI和VS的异常检测方法,第二种是基于upper的异常检测方法,下面将分类讨论。
(一)基于DLI和VS的异常检测方法
图9是本申请实施例提供的一种获取异常识别子信息的流程图,请参考图9,示出了节点设备如何基于一致性检验算法获取异常识别子信息,这里针对某一次循环过程进行展开说明。
901、对于至少一个并发事务中任一并发事务,节点设备根据目标事务与该任一并发事务的读写集合,获取第一集合S1、第二集合S2以及第三集合S3。
其中,S1为目标事务的读集与该任一并发事务的写集之间的交集,S2为目标事务的写集与该任一并发事务的读集之间的交集,S3为目标事务的写集与该任一并发事务的写集之间的交集。
在上述过程中,节点设备在进入验证阶段的时候,假设当前进入验证阶段的待判断的目标事务为T,目标事务T最开始初始值是一个物理事务,在经过动边合并后变成一个逻辑事务。进一步地,节点设备为动边交叉值DLI以及变量状态值VS配置初始值,可以将两者的初始值都配置为0,也即令DLI=0;VS=0。
在对DLI以及VS初始化完毕后,节点设备对链表TS中每个并发事务循环执行获取异常识别子信息的操作,一旦任一异常识别子信息为存在数据异常,退出循环并将最终的异常识别信息确定为存在数据异常,否则,继续对链表TS中下一并发事务执行循环,直到链表TS为空,所有的异常识别子信息均为不存在数据异常,结束循环并将最终的异常识别信息确定为不存在数据异常。
上述步骤901即为对任一并发事务TL执行的循环操作的第一个步骤,此时节点设备根据目标事务T和该任一并发事务TL的读写集合,将目标事务T的读集与该任一并发事务TL的写集之间的交集确定为第一集合S1,第一集合S1表示为“S1=DSR(T)∩DSW(TL)”,将目标事务T的写集与该任一并发事务TL的读集之间的交集确定为第二集合S2,第二集合S2表示为“S2=DSR(TL)∩DSW(T)”,将目标事务T的写集与该任一并发事务TL的写集之间的交集确定为第三集合S3,第三集合S3表示为“S3=DSW(T)∩DSW(TL)”。
可选地,在获取S1、S2、S3时,使用哈希表存储TL和T各自的读写集合,从而能够在线性时间复杂度内得到他们的交集和并集。
需要说明的是,如果S1、S2、S3三者之间的并集为空集,也即S1∪S2∪S3为空集(简化计算:
Figure GDA0002650580260000441
Figure GDA0002650580260000442
Figure GDA0002650580260000443
也即S1、S2、S3均为空集),则说明TL和目标事务T不是并发事务,节点设备需要把TL重新加入链表TS的尾部。否则,如果S1、S2、S3三者之间的并集不是空集,说明TL和目标事务T是并发事务,此时执行下述步骤902-903进行异常检测,如果发现异常,回滚目标事务T。
902、节点设备响应于该第三集合S3不是空集,根据该任一并发事务的提交情况获取该任一并发事务与该目标事务之间的异常识别子信息。
在一些实施例中,若该任一并发事务TL未提交且该目标事务T的目标参数为一,将该异常识别子信息获取为存在数据异常且数据异常类型为谓词脏写异常,其中,该目标参数T.no_committed用于表示该目标事务的读写集合成分所对应的已提交事务数量,由于在循环过程中,如果上一个并发事务与目标事务之间的异常识别子信息为不存在数据异常,那么在执行本次循环之前,需要将上一个并发事务与目标事务进行动边合并,并将动边合并后得到的新的事务赋值给目标事务,而动边合并的本质是对两事务的读写集合进行合并,因此在任一次循环中,目标事务的读写集合有可能是经过合并后的读写集合,在目标事务的读写集合中会拥有某个已经提交的事务的读写集合的成分,而目标参数T.no_committed则用来描述读写集合中所拥有的其他已提交事务的成分所对应的已提交事务数量。
在一些实施例中,若该任一并发事务TL已提交且该第一集合S1与该第三集合S3之间的交集不是空集,将该异常识别子信息获取为存在数据异常且数据异常类型为谓词丢失更新异常。
也即是说,如果
Figure GDA0002650580260000444
满足如下任一条件时,节点设备将异常识别子信息获取为存在数据异常,并将最终的异常识别信息获取为存在数据异常,报告写写异常发生,循环终止:1)该任一并发事务TL没有提交完成且该目标事务T的目标参数T.no_committed=1,此时构成写写冲突,数据异常类型为谓词脏写异常;2)该任一并发事务TL已经提交且S1∩S3不是空集,此时数据异常类型为谓词丢失更新异常。当
Figure GDA0002650580260000451
时,执行下述步骤903。
903、节点设备响应于该第三集合S3是空集且该第一集合S1或者该第二集合S2中至少一项不是空集,根据该第一集合S1和该第二集合S2获取该异常识别子信息。
在一些实施例中,节点设备可以根据该第一集合和该第二集合,更新该任一并发事务与该目标事务之间的动边交叉值DLI和变量状态值VS,基于更新后的动边交叉值DLI和更新后的变量状态值VS,获取该异常识别子信息。
Figure GDA0002650580260000452
的基础上,如果满足
Figure GDA0002650580260000453
或者
Figure GDA0002650580260000454
中至少一项,节点设备根据如下更新规则对DLI和VS进行更新:
1)节点设备响应于该第一集合S1不是空集,将动边交叉值DLI更新为已有值加一所得的数值,也即:S1不为空,则DLI=DLI++;响应于该第一集合S1中存在数据状态不同的变量,将变量状态值VS更新为已有值加一所得的数值,也即:如S1中存在某个非空元素的数据状态不同,则VS=VS++。
2)节点设备响应于该第二集合S2不是空集,将动边交叉值DLI更新为已有值加一所得的数值,也即:S2不为空,则DLI=DLI++;响应于该第二集合S2中存在数据状态不同的变量,将变量状态值VS更新为已有值加一所得的数值,也即:如S2中存在某个非空元素的数据状态不同,则VS=VS++。
在一些实施例中,在对DLI和VS进行更新后,节点设备可以基于下式方式来获取该异常识别子信息:节点设备响应于该更新后的动边交叉值DLI大于或等于二,将该异常识别子信息获取为存在数据异常,并基于该更新后的变量状态值VS,确定数据异常类型;否则,将该异常识别子信息获取为不存在数据异常。
在一些实施例中,节点设备在基于更新后的VS确定数据异常类型时,可以响应于该更新后的变量状态值为一,确定该数据异常类型为谓词读异常,也即是VS=1,报告谓词读异常,读异常包括1个变量的谓词不可重复读异常、2个变量的谓词读偏序异常、3个及3个以上变量的谓词台阶式异常;响应于该更新后的变量状态值VS大于或等于二,确定该数据异常类型为谓词写异常,也即是VS≥2,报告谓词写异常,写异常包括2个变量的谓词写偏序异常、谓词3个及3个以上变量的谓词锯齿波异常。
在上述过程中,如果DLI≥2,说明目标事务T和TL构成动边交叉,则报告异常发生,将异常识别子信息以及异常识别信息确定为存在数据异常,循环终止(VS=1时数据异常类型为谓词读异常,VS≥2时数据异常类型为谓词写异常);否则,没有任何异常,将TL和目标事务T进行动边合并,设定得到的新的事务为T-new,并将T-new赋值给目标事务T(T=T-new),从链表TS中取出第二个事务定为TL,执行下一次循环(判断新的T-new与新的TL之间是否存在动边交叉)。
在上述动边合并的过程中,节点设备可以将该任一并发事务TL的读集并入目标事务T的读集中,将该任一并发事务TL的写集并入目标事务T的写集中,此外,如果事务TL没有提交,则令T-new的目标参数自增1,也即令T-new.no_committed++(自增1),表示合并得到的新事务中拥有某个已经提交的事务的读写集合的成分。
进一步地,如果循环结束时,仍没有异常报告,则代表目标事务可提交。可选地,如果隔离级别参数=S,也即隔离级别是可串行化级别,此时即可满足可串行化级别,否则,系统可以在允许某些类型的数据异常发生的情况下,满足所设定的隔离级别。
(二)基于upper的异常检测方法
图10是本申请实施例提供的一种获取异常识别子信息的流程图,请参考图10,示出了节点设备如何基于一致性检验算法获取异常识别子信息,这里针对某一次循环过程进行展开说明。
1001、对于至少一个并发事务中任一并发事务,节点设备根据目标事务与该任一并发事务的读写集合,获取第一集合S1、第二集合S2、第三集合S3以及第四集合S4。
其中,S1为目标事务的读集与该任一并发事务的写集之间的交集,S2为目标事务的写集与该任一并发事务的读集之间的交集,S3为目标事务的写集与该任一并发事务的写集之间的交集,S4为目标事务的读集与该任一并发事务的读集之间的交集。
在上述过程中,节点设备在进入验证阶段的时候,假设当前进入验证阶段的待判断的目标事务为T,目标事务T最开始初始值是一个物理事务,在经过动边合并后变成一个逻辑事务。
进一步地,节点设备为目标事务T以及该任一并发事务TL的布尔型upper配置初始值,可以将两者的初始值都配置为false,也即令T.upper=false;TL.upper=false。该布尔型upper表示的是事务所构成的动边在数据状态矩阵中的垂直位置关系,以任意两个并发事务Ti和Tj为例,若Ti.upper=true,则表明事务Ti在某变量上构成的动边相对另一事务Tj较新,也即是说,针对同一变量而言,事务Ti在该变量上操作了比事务Tj较新的变量版本。
在对两事务的upper值初始化完毕后,节点设备对链表TS中每个并发事务循环执行获取异常识别子信息的操作,一旦任一异常识别子信息为存在数据异常,退出循环并将最终的异常识别信息确定为存在数据异常,否则,继续对链表TS中下一并发事务执行循环,直到链表TS为空,所有的异常识别子信息均为不存在数据异常,结束循环并将最终的异常识别信息确定为不存在数据异常。
上述步骤1001即为对任一并发事务TL执行的循环操作的第一个步骤,此时节点设备根据目标事务T和该任一并发事务TL的读写集合,将目标事务T的读集与该任一并发事务TL的写集之间的交集确定为第一集合S1,第一集合S1表示为“S1=DSR(T)∩DSW(TL)”,将目标事务T的写集与该任一并发事务TL的读集之间的交集确定为第二集合S2,第二集合S2表示为“S2=DSR(TL)∩DSW(T)”,将目标事务T的写集与该任一并发事务TL的写集之间的交集确定为第三集合S3,第三集合S3表示为“S3=DSW(T)∩DSW(TL)”,将目标事务T的读集与该任一并发事务TL的读集之间的交集确定为第四集合S4,第四集合S4表示为“S4=DSR(TL)∩DSR(T)”。
可选地,在获取S1、S2、S3、S4时,可以使用哈希表存储TL和T各自的读写集合,从而能够在线性时间复杂度内得到他们的交集和并集。
需要说明的是,如果S1、S2、S3、S4三者之间的并集为空集,也即S1∪S2∪S3∪S4为空集(简化计算:
Figure GDA0002650580260000471
Figure GDA0002650580260000472
Figure GDA0002650580260000473
Figure GDA0002650580260000474
也即S1、S2、S3、S4均为空集),则说明TL和目标事务T不是并发事务,节点设备需要把TL重新加入链表TS的尾部。否则,如果S1、S2、S3、S4三者之间的并集不是空集,说明TL和目标事务T是并发事务,此时执行下述步骤1002-1003进行异常检测,如果发现异常,回滚目标事务T。
1002、节点设备响应于S3不是空集,根据该任一并发事务的提交情况获取该任一并发事务与该目标事务之间的异常识别子信息。
上述步骤1002与上述步骤902类似,这里不做赘述。
1003、节点设备响应于S3是空集且S1、S2或者S4中至少一项不是空集,根据S1、S2以及S4获取该异常识别子信息。
在一些实施例中,节点设备可以根据S1、S2和S4,更新该任一并发事务TL的布尔型TL.upper与该目标事务T的布尔型T.upper,基于更新后的TL.upper和更新后的T.upper,获取该异常识别子信息。其中,该布尔型用于表示对应事务所构成的动边在数据状态矩阵中的垂直位置关系且该布尔型的初始值为假(false)。
具体地,在基于更新后的TL.upper和更新后的T.upper,获取该异常识别子信息时,可以执行如下处理:节点设备响应于更新后的该目标事务的布尔型和更新后的该任一并发事务的布尔型均为真T.upper=TL.upper=true,将该异常识别子信息获取为存在数据异常;否则,将该异常识别子信息获取为不存在数据异常。
Figure GDA0002650580260000481
的基础上,如果满足
Figure GDA0002650580260000482
或者
Figure GDA0002650580260000483
中至少一项,节点设备根据如下更新规则对TL.upper和T.upper进行更新:
1)节点设备响应于S1不是空集,对于S1中任一变量,若该变量在目标事务的读集中的版本号大于或等于该变量在该任一并发事务的写集中的版本号,将该目标事务的布尔型更新为真;否则,将该任一并发事务的布尔型更新为真。
也即是说,对于S1中的每一个变量x,若该目标事务T读变量x的版本≥该任一并发事务TL写变量x的版本,比如该目标事务T读取变量版本x2、该任一并发事务TL写入变量版本x1,则置T.upper=true,否则,若该目标事务T读变量x的版本<该任一并发事务TL写变量x的版本,比如该目标事务T读取变量版本x1、该任一并发事务TL写入变量版本x2,则置TL.upper=true。
2)节点设备响应于S2不是空集,对于S2中任一变量,若该变量在目标事务的写集中的版本号大于该变量在该任一并发事务的读集中的版本号,将该目标事务的布尔型更新为真;否则,将该任一并发事务的布尔型更新为真。
也即是说,对于S2中的每一个变量x,若该目标事务T写变量x的版本>该任一并发事务TL读变量x的版本,比如该目标事务T写入变量版本x2、该任一并发事务TL读取变量版本x1,则置T.upper=true,否则,若该目标事务T写变量x的版本≤该任一并发事务TL读变量x的版本,比如该目标事务T写入变量版本x1、该任一并发事务TL读取变量版本x2,则置TL.upper=true。
3)节点设备响应于S4不是空集,对于S4中任一变量,若该变量在目标事务的读集中的版本号大于该变量在该任一并发事务的读集中的版本号,将该目标事务的布尔型更新为真;若该变量在目标事务的读集中的版本号小于该变量在该任一并发事务的读集中的版本号,将该任一并发事务的布尔型更新为真。
也即是说,对于S4中的每一个变量x,若该目标事务T读变量x的版本>该任一并发事务TL读变量x的版本,比如该目标事务T读取变量版本x2、该任一并发事务TL读取变量版本x1,则置T.upper=true;若该目标事务T读变量x的版本<该任一并发事务TL读变量x的版本,比如该目标事务T读取变量版本x1、该任一并发事务TL读取变量版本x2,则置TL.upper=true;若该目标事务T读变量x的版本=该任一并发事务TL读变量x的版本,比如该目标事务T和该任一并发事务TL均读取了变量版本x1,则不做任何操作。
在S3为空集的情况下,可以保证满足基本规则中禁止写写冲突发生的条件,也即禁止谓词脏写数据异常。在以上述规则1)-3)中,分别对该目标事务T的读集和该任一并发事务TL的写集进行比较(分析S1中的元素)、对该目标事务T的写集和该任一并发事务TL的读集进行比较(分析S2中的元素)、对该目标事务T的读集和该任一并发事务TL的读集进行比较(分析S4中的元素)之后,分别对该目标事务T的布尔型T.upper和该任一并发事务TL的布尔型TL.upper进行更新,若在更新完毕后,满足如下条件:T.upper=TL.upper=true,则认为存在动边交叉,也即存在数据异常,此时将该异常识别子信息获取为存在数据异常;否则,将该异常识别子信息获取为不存在数据异常。
在上述过程中,如果最终T.upper=TL.upper=true,说明该目标事务T和该任一并发事务TL构成动边交叉,则报告异常发生,将异常识别子信息以及异常识别信息确定为存在数据异常,循环终止;否则,没有任何异常,将该任一并发事务TL和该目标事务T进行动边合并,设定得到的新的事务为T-new,并将T-new赋值给目标事务T(T=T-new),从链表TS中取出第二个事务定为TL,执行下一次循环(判断新的T-new与新的TL之间是否存在动边交叉)。
在上述动边合并的过程中,节点设备可以将该任一并发事务TL的读集并入该目标事务T的读集中,将该任一并发事务TL的写集并入该目标事务T的写集中,此外,如果该任一并发事务TL没有提交,则令T-new的目标参数自增1,也即令T-new.no_committed++(自增1),表示合并得到的新事务中拥有某个已经提交的事务的读写集合的成分。
进一步地,如果循环结束时,仍没有异常报告,则代表该目标事务可提交。可选地,如果隔离级别参数=S,也即隔离级别是可串行化级别,此时即可满足可串行化级别,否则,系统可以在允许某些类型的数据异常发生的情况下,满足所设定的隔离级别。
本申请实施例提供的面向集合的动边交叉与合并算法(SDLI-M),使用到多次集合的运算,对于这些运算,可以使用哈希表作为集合的数据结构,从而可在线性时间复杂度内得到他们的交集和并集,时间复杂度为O(m+n)。SDLI-M算法再每次循环中,通过5次的集合并交计算,即能识别并发事务之间是否存在数据异常。而循环次数最多达到并发事务的个数k,因此总的算法复杂度应为:O(k*(m+n))。最坏的情况是,每一个事务只有1到2个并发事务,且循环执行了k-1次,才找到可合并的并发事务,这导致复杂度变为O(k2*(m+n))。但实际情况通常是,随着事务动边合并的推进,余下的事务个数在减少,因此复杂度为O(k*lgk*(m+n))。
上述所有可选技术方案,能够采用任意结合形成本公开的可选实施例,在此不再一一赘述。
在本申请实施例中,在上述SDLI-M算法的基础上,采用快照技术、融合静边和动边概念,可以实现数据库系统的多种隔离级别,这一算法称为基于快照的面向集合的动边交叉与合并算法(Snapshot-based SDLI-M,SSDLI-M),该SSDLI-M算法可以考虑耦合或者解耦乐观并发控制算法(Optimistic Concurrency Control,OCC),此外,在本实施例中的SSDLI-M算法还可以针对上述实施例中SDLI-M算法的一些细节进行优化,从而达到对SDLI-M算法的改进,下面进行详述。
1、读写阶段事务读写集形成算法
在目标事务开始执行时,初始化目标事务的读集和写集为空集。
对于谓词读操作来说,如果谓词(也即过滤条件)包括的变量被读取,则将被读取的变量全部加入到读集中;对于谓词写操作来说,如果谓词包括的变量被写入,则将被写入的变量全部加入到写集中。
例如,当目标事务对谓词包括的某个变量x进行更新时,将变量x添加至目标事务的写集中,为变量x分配版本号。不同事务对同一个变量的写操作的版本号按整数递增。新发生的读操作也因此可获得变量的版本号,即为每个变量维护一个递增的版本号。
目标事务的读集和写集随着事务操作的进行而实时维护。同一个事务写同一个变量版本多次则有多个不同新的版本,在写集中用最新的版本替代旧的变量版本。
在一些实施例中,由于基于集合的谓词运算会把谓词表达式(也即过滤条件)所确定的数据项作为一个子集合加入到目标事务的读写集合中,如果初始的谓词表达式所操作的子集合为空集,也即没有任何数据对象被谓词表达式所选定时,此时没有任何数据对象被加入到目标事务的读写集合中。
在一个示例性场景中,例如在给定工作表(workhours)的操作中,如果谓词表达式没有索引到任何数据项,不会有具有的数据项被添加到目标事务的读写集合中,这时假设系统存在谓词写偏序异常,那么在利用SSDLI-M算法进行判断的时候,由于读写集合中没有数据项,不能构成动边交叉,将会产生不存在数据异常的误判情况。针对上述情况,本申请实施例提供以下两种解决方式:
方式一、对目标事务的每个谓词设置一个逻辑对象,在读写集合的维护阶段中,将逻辑对象加入到读写集合中,用该逻辑对象(可以包括0到任意数量的数据项)作为数据状态矩阵中的一个状态点,当然在矩阵图中对应于一个圆圈点,如果该逻辑对象内有某个数据项被其他事务读过或写过,则依然可以按照事务画出一致性状态边,因此能够构成动边交叉,并按照动边交叉与合并算法进行判断。尤其是在无数据项的情况下,也能够通过构造一个逻辑对象而在数据状态矩阵中构造出一个实体的圆圈点,以便于后续进行动边交叉检验,识别出是否存在多变量的数据异常。
方式二、直接在谓词锁操作的数据对象上施加排他锁,此后对谓词范围内其他并发事务的操作均会被排他锁阻塞,可以直接避免谓词写偏序异常的发生。
上述初始化过程以及读写集合的维护策略与SDLI-M算法类似,这里不做赘述。
SSDLI-M算法与SDLI-M算法的区别在于,SSDLI-M算法在读取过程中所读取的数据,并不是SDLI-M算法中“最新的满足读已提交规则的数据”,而是距离快照St时间点最近且最合适的静边上的相关数据,可以满足数据的一致性状态。
具体地,在数据读取过程中遵循数据项的可见性判断算法:基于时间戳,建立一个快照Snapshot Set=Ss={St},St是一个时间点。在每个数据项的基本数据结构中,存储有一个产生该数据项的事务的事务号tid和一个产生该数据项的事务的提交时间戳tc(若该数据版本未提交则tc=NULL)。如果一个数据项的tc非NULL且tc<St,则该版本可被快照读取,也即该数据项为相对于目标事务可见的目标数据项,但是所有的版本之间存在一个从最新版本到最老版本之间的一个版本链(也即历史序列),读取版本的时候从最新版本开始。
需要说明的是快照时间点St、事务标识tid、提交时间戳tc三者都属于同一个数据类型,如都是同一个数值型逻辑时间戳值,或都是类似HLC(混合逻辑时钟)的时间戳值,只要可以进行偏序比较大小即可。这一可见性判断算法保证了一个事务读取的数据是距离St时间点最近且最合适的静边上的相关数据,即保证读取的数据满足数据的一致性状态。
2、数据读取阶段
在一些实施例中,在SSDLI-M算法的数据读取阶段,节点设备对于目标事务的任一次读操作,可以确定该读操作的快照;根据该读操作的读取条件以及该读操作的快照,确定相对于该目标事务可见的目标数据项,将该目标数据项添加至该目标事务的读集中。
可选地,在快照可重复读历史以及其以上的隔离级别中,节点设备可以将该目标事务第一次读操作的快照确定为该读操作的快照。也即是说,在读取数据的时候,如果隔离级别参数≥SRR(隔离级别高于或等于SRR),仅在第一次执行读操作时获取快照,后续每次读操作均使用第一次获取的快照来读取数据,这种情况下只使用第一次的快照,可避免谓词不可重复读异常/幻读异常发生。需要说明的是,此时是避免发生某一类数据异常,而不是在检测发现异常然后回滚事务,所以没有报告异常并终结事务的步骤。
在一些实施例中,在可见性判断算法中,节点设备响应于数据库系统的隔离级别高于或等于读写已提交RWC,将符合该读取条件且提交时间戳tc小于该读操作的快照St的最大版本确定为目标数据项;响应于数据库系统的隔离级别低于读写已提交RWC,若符合该读取条件的数据项中存在未提交版本,将最大的未提交版本确定为目标数据项。
也即是说,当隔离级别参数≥RWC时,与上述“读写阶段事务读写集形成算法”中所涉及的可见性判断算法保持一致,这里不做赘述,但当隔离级别参数<RWC时,可以对前述可见性判断算法进行修改,使得最新的一个未提交版本可以被读取到,从而实现了RWU级别。
在一些实施例中,如果采用OCC框架,在隔离级别参数>SRR时,则对于每个事务中的第二个读操作,先从读集和写集中验证是否存在要读取的对象,如果存在,再从读写集合中获取;否则,需要从底层的存储层内获取。
3、每个操作发生时,执行准备阶段算法
在目标事务T的每个操作(或读或写)发生时,进入准备阶段并开始做准备工作,准备阶段用于为目标事务T是否可提交做好事务并发访问控制异常验证前的准备工作。
在准备阶段中,节点设备进入临界区,遍历目标事务T的读集和写集,找出目标事务T的所有并发事务的事务标识,放入一个链表TS内进行存储,在找到后退出临界区。在内存中,每个数据项上存有曾经读写过本数据项但尚未提交的事务的事务标识。
SSDLI-M算法的准备阶段算法与上述SDLI-M算法所介绍的准备阶段算法类似,这里不做赘述。
在一些实施例中,SSDLI-M算法与OCC算法耦合时,准备阶段的算法对应于OCC的验证阶段。
在一些实施例中,SSDLI-M算法可以针对SDLI-M算法进行如下改进:如果已有链表oldTS不为空,则把目标事务直接加入到TS中(也即令TS=oldTS+T),不再遍历目标事务的读集和写集,从而可以减少对读写集合的遍历逻辑,从而可提高事务处理效率。
4、每个操作发生时,执行一致性检验算法(也即改进的动边交叉与合并算法)
在一些实施例中,SSDLI-M算法与OCC算法耦合时,一致性检验算法对应于OCC的验证阶段,不再是每个操作发生时执行一次,而是在OCC的验证阶段执行。
在SSDLI-M算法中改进的动边交叉与合并算法与SDLI-M算法中的动边交叉与合并算法相类似,这里对类似的步骤不做详细展开,改进的动边交叉与合并算法仍然包括两种不同的类型,第一种是改进的基于DLI和VS的异常检测方法,第二种是改进的基于upper的异常检测方法,下面将分类讨论。
(一)改进的基于DLI和VS的异常检测方法
(4.1)当前进入验证阶段的待判断的目标事务为T,此事务T的初始值是一个物理事务,在经过动边合并之后变成一个逻辑事务。
(4.2)对DLI和VS进行初始化。也即是设定一些隶属变量的初始值:DLI=0;VS=0。
(4.3)从链表TS中取出第一个事务定为TL,循环执行下述操作,直到链表为空:
(4.3.1)获取第一集合S1=DSR(T)∩DSW(TL),S1为目标事务T的读集和并发事务TL的写集之间的交集。S1不为空,则DLI=DLI++;如S1中某个非空元素的数据状态不同,则VS=VS++。
(4.3.2)获取第二集合S2=DSR(TL)∩DSW(T),S2为目标事务T的写集和并发事务TL的读集之间的交集。S1不为空,则DLI=DLI++;如S2中某个非空元素的数据状态不同,则VS=VS++。
(4.3.3)获取第三集合S3=DSW(T)∩DSW(TL),S3为目标事务T的写集和并发事务TL的写集之间的交集。
(4.3.4)如果S1∪S2∪S3为空集(简化计算为:
Figure GDA0002650580260000541
Figure GDA0002650580260000542
Figure GDA0002650580260000543
),则说明TL和T不是并发事务,把TL重新加入到链表TS的尾部。
(4.3.5)否则,S1∪S2∪S3不为空集,说明S1、S2、S3中至少存在一个集合不是空集,此时TL和T是并发事务,进行异常检测,一旦发现异常,需要报告异常并回滚目标事务T。异常检测过程遵循下述规则:
(4.3.5.1)如果
Figure GDA0002650580260000544
在满足如下两种条件中任一项时,节点设备则报告写写异常发生,循环终止。
条件一、如果隔离级别参数!=RWU(只有RWU级别不禁止脏写异常),TL没有提交完成且T.no_committed=1,存在写写冲突,数据异常类型为谓词脏写异常。
条件二、如果隔离级别参数≥SRR(SRR级别禁止丢失更新发生,所以高于或等于SRR的隔离级别均报告此异常),TL已经提交且S1∩S3不是空集,上报数据异常,数据异常类型为谓词丢失更新异常。
(4.3.5.2)否则,在
Figure GDA0002650580260000551
的条件下,如果
Figure GDA0002650580260000552
或者
Figure GDA0002650580260000553
可以分为如下三种情况进行讨论:
情况一、如果目标事务T和TL构成动边交叉,则报告异常发生,循环终止。在一些实施例中,DLI≥2时,认为目标事务T与TL之间构成动边交叉,此时节点设备可以根据隔离级别确定是否报告异常发生并使得循环终止,并根据VS来确定数据异常类型。
可选地,如果隔离级别参数≥SRR(禁止谓词读偏序异常和谓词台阶式异常),且VS=1,则报告异常发生并使得循环终止,此时数据异常类型为谓词读异常,包括2个变量的谓词读偏序异常、3个及3个以上变量的谓词台阶式异常(1个变量的谓词不可重复读异常已经在数据读取阶段中被识别了,在异常检测阶段无需进行重复识别)。
可选地,如果隔离级别参数=S(禁止谓词写偏序异常和谓词锯齿波异常),且VS≥2,则报告异常发生并使得循环终止,此时数据异常类型为谓词写异常,包括2个变量的谓词写偏序异常、3个及3个以上变量的谓词锯齿波异常。
情况二、否则,如果目标事务T和TL没有构成动边交叉,在隔离级别参数=S的情况下,节点设备还需要检查是否存在完整性约束,如果本事务所读写的数据违反了完整性约束,则报告异常发生并使得循环终止。
情况三、否则,如果目标事务T和TL没有构成动边交叉,且符合完整性约束,那么没有任何异常,对目标事务T和TL进行动边合并,设定新的事务为T-new。
在动边合并过程中,节点设备把并发事务TL的读集并入目标事务T的读集,将并发事务TL的写集并入目标事务T的写集;如果并发事务TL没有提交,则令T-new的目标参数T-new.no_committed++(自增1),表示合并得到的新事务中拥有某个已经提交的事务的读写集的成分;令T=T-new,用T-new给T赋值,然后执行下一次循环。
(4.3.6)如果循环结束,没有异常报告,则目标事务T可以提交。如果隔离级别参数=S则保证了可串行化。
(4.3.7)在SSDLI-M算法中,还可以记录本次异常检测的链表TS,从中去除本次事务,供下次使用,使得oldTS=TS-T,达到oldTS的实时维护。可选地,TS里面还可以有很多合并后的逻辑事务,使得TS的长度变小,一方面节约了存储空间,另一方面有助于加速后续每个操作的判断。
在一些实施例中,通过使用哈希表作为集合的数据结构,可以在线性时间复杂度内得到不同集合之间的交集或者并集。
(二)改进的基于upper的异常检测方法
(4.1)当前进入验证阶段的待判断的目标事务为T,此事务T的初始值是一个物理事务,在经过动边合并之后变成一个逻辑事务。
(4.2)从链表TS中取出第一个事务定为TL,分别对T.upper和TL.upper进行初始化,也即是设定一些隶属变量的初始值:T.upper=false;TL.upper=false。
(4.3)对两事务T、TL的upper值初始化完毕后,循环执行下述操作,直到链表为空:
(4.3.1)获取第一集合S1=DSR(T)∩DSW(TL),S1为目标事务T的读集和并发事务TL的写集之间的交集。对于S1中的每一个变量x,若目标事务T读变量x的版本≥并发事务TL写变量x的版本,则置T.upper=true;否则,置TL.upper=true。
(4.3.2)获取第二集合S2=DSR(TL)∩DSW(T),S2为目标事务T的写集和并发事务TL的读集之间的交集。对于S2中的每一个变量x,若目标事务T写变量x的版本>并发事务TL读变量x的版本,则置T.upper=true;否则,置TL.upper=true。
(4.3.3)获取第三集合S3=DSW(T)∩DSW(TL),S3为目标事务T的写集和并发事务TL的写集之间的交集。
(4.3.4)获取第四集合S4=DSR(TL)∩DSR(T),S4为目标事务T的读集和并发事务TL的读集之间的交集。对于S4中的每一个变量x,若目标事务T读变量x的版本>并发事务TL读变量x的版本,则置T.upper=true;若目标事务T读变量x的版本<并发事务TL读变量x的版本,则置TL.upper=true;若目标事务T读变量x的版本=并发事务TL读变量x的版本,则不做任何操作。
(4.3.5)如果S1∪S2∪S3∪S4为空集(简化计算为:
Figure GDA0002650580260000564
Figure GDA0002650580260000563
Figure GDA0002650580260000562
Figure GDA0002650580260000561
),则说明TL和T不是并发事务,把TL重新加入到链表TS的尾部。
(4.3.6)否则,S1∪S2∪S3∪S4不为空集,说明S1、S2、S3、S4中至少存在一个集合不是空集,此时TL和T是并发事务,进行异常检测,一旦发现异常,需要报告异常并回滚目标事务T。异常检测过程遵循下述规则:
(4.3.6.1)如果
Figure GDA0002650580260000571
在满足如下两种条件中任一项时,节点设备则报告写写异常发生,循环终止。
条件一、如果隔离级别参数!=RWU(只有RWU级别不禁止脏写异常),TL没有提交完成且T.no_committed=1,存在写写冲突,数据异常类型为谓词脏写异常。
条件二、如果隔离级别参数≥SRR(SRR级别禁止丢失更新发生,所以高于或等于SRR的隔离级别均报告此异常),TL已经提交且S1∩S3不是空集,上报数据异常,数据异常类型为谓词丢失更新异常。
(4.3.6.2)否则,在
Figure GDA0002650580260000572
的条件下,如果
Figure GDA0002650580260000573
或者
Figure GDA0002650580260000574
可以分为如下三种情况进行讨论:
情况一、如果目标事务T和TL构成动边交叉,则报告异常发生,循环终止。在一些实施例中,T.upper=TL.upper=true时,认为目标事务T与TL之间构成动边交叉,此时节点设备可以报告异常发生并使得循环终止。
情况二、否则,如果目标事务T和TL没有构成动边交叉,在隔离级别参数=S的情况下,节点设备还需要检查是否存在完整性约束,如果本事务所读写的数据违反了完整性约束,则报告异常发生并使得循环终止。
情况三、否则,如果目标事务T和TL没有构成动边交叉,且符合完整性约束,那么没有任何异常,对目标事务T和TL进行动边合并,设定新的事务为T-new。
在动边合并过程中,节点设备把并发事务TL的读集并入目标事务T的读集,将并发事务TL的写集并入目标事务T的写集;如果并发事务TL没有提交,则令T-new的目标参数T-new.no_committed++(自增1),表示合并得到的新事务中拥有某个已经提交的事务的读写集的成分;令T=T-new,用T-new给T赋值,然后执行下一次循环。
(4.3.7)如果循环结束,没有异常报告,则目标事务T可以提交。如果隔离级别参数=S则保证了可串行化。
(4.3.8)在SSDLI-M算法中,还可以记录本次异常检测的链表TS,从中去除本次事务,供下次使用,使得oldTS=TS-T,达到oldTS的实时维护。可选地,TS里面还可以有很多合并后的逻辑事务,使得TS的长度变小,一方面节约了存储空间,另一方面有助于加速后续每个操作的判断。
在一些实施例中,通过使用哈希表作为集合的数据结构,可以在线性时间复杂度内得到不同集合之间的交集或者并集。
本申请实施例提供的SSDLI-M算法的效率与上述实施例中SDLI-M算法的效率相同,可以适用于单机数据库系统的事务处理。在SSDLI-M算法中,响应于异常识别信息为存在数据异常,节点设备可以根据数据异常类型以及数据库系统的隔离级别,确定目标事务的执行结果,该执行结果用于表示提交该目标事务或者回滚该目标事务,从而实现了多个不同的隔离级别。
在一些实施例中,响应于数据异常类型包括谓词脏写异常且该隔离级别不为读写未提交RWU,将该执行结果确定为回滚该目标事务(对应于4.3.5.1的条件一);响应于数据异常类型包括谓词丢失更新异常且该隔离级别高于或等于快照可重复读历史SRR,将该执行结果确定为回滚该目标事务(对应于4.3.5.1的条件二);响应于数据异常类型包括谓词读异常且该隔离级别高于或等于快照可重复读历史SRR,将该执行结果确定为回滚该目标事务(对应于4.3.5.2的情况一中隔离级别参数≥SRR的描述);响应于数据异常类型包括谓词写异常且该隔离级别等于可串行化S,将该执行结果确定为回滚该目标事务(对应于4.3.5.2的情况一中隔离级别参数=S的描述)。
上述所有可选技术方案,能够采用任意结合形成本公开的可选实施例,在此不再一一赘述。
上述实施例中提供的SSDLI-M算法能够应用于单机数据库系统的事务处理,而在本申请实施例中,将提供一种面向分布式数据库系统的、基于快照的且面向集合的动边交叉与合并算法(Disdtributed Snapshot-based SDLI-M,DSSDLI-M),在介绍DSSDLI-M算法之前,首先对分布式事务-父子事务之间的隔离级别的关系进行说明。
在分布式数据库系统中,如果父事务的隔离级别强于子事务的隔离级别,则强制子事务的隔离级别同父事务的隔离级别保持一致,即父事务的隔离级别代表整个系统的隔离级别。如果父事务的隔离级别弱于子事务的隔离级别,对于单变量的事务,由于其不可能构成分布式事务,则强制父事务的隔离级别同子事务的隔离级别保持一致,即子事务的隔离级别代表整个系统的隔离级别。对于多变量的事务,由于有可能构成分布式异常,因此需要定义新的级别,从弱到强分为A、B、C三级。分布式事务-父子事务之间的隔离级别的关系如下表6所示。
表6
Figure GDA0002650580260000591
其中,“快照可重复读”也即是快照可重复读历史SRR级别的简称,后文不做赘述。下面分别针对新定义的隔离级别进行说明。
1)A-弱2级别:父事务读写未提交+子事务快照可重复读(父RWU+子SRR),遵从子快照可重复读,整体允许分布式谓词读偏序、分布式谓词读写偏序、分布式谓词台阶式、分布式谓词写偏序、分布式谓词锯齿波等数据异常。
2)A-弱1级别:父事务读写未提交+子事务可串行化(父RWU+子S),遵从子可串行化,整体允许分布式谓词读偏序、分布式谓词读写偏序、分布式谓词台阶式、分布式谓词写偏序、分布式谓词锯齿波等数据异常。
3)B-弱2级别:父事务读写已提交+子事务快照可重复读(父RWC+子SRR),遵从子快照可重复读,整体允许分布式谓词读偏序、分布式谓词读写偏序、分布式谓词台阶式、分布式谓词写偏序、分布式谓词锯齿波等数据异常。
4)B-弱1级别:父事务读写已提交+子事务可串行化(父RWC+子S),遵从子可串行化,整体允许分布式谓词读偏序、分布式谓词读写偏序、分布式谓词台阶式、分布式谓词写偏序、分布式谓词锯齿波等数据异常。
5)C-弱1级别:父事务快照可重复读+子事务可串行化(父SRR+子S),遵从子可串行化,整体允许分布式谓词读偏序、分布式谓词读写偏序、分布式谓词台阶式、分布式谓词写偏序、分布式谓词锯齿波等数据异常。
分布式事务的隔离级别,可以具有如下2种定义形式:
第一种、两级分布式事务隔离级别:如表6定义,父事务和子事务可各自定义各自的隔离级别,但整体事务遵从表6中隔离级别的定义。
第二种、统一的分布式事务隔离级别:如表6中加粗字体的方格定义,父事务和子事务不可各自定义各自的隔离级别,整体事务遵从表6的定义中加粗字体的方格定义。
在提供了上述分布式事务的隔离级别的基础上,针对上述统一的分布式事务隔离级别(第二种分布式事务隔离级别),在本申请实施例中,基于SSDLI-M算法还提供了DSSDLI-M算法,采用全局快照技术,可以应用于分布式事务型数据库系统,下面进行详述。
1、快照点的建立方法,全局快照点构建法
(1.1)采用HLC算法构造全局的混合逻辑时钟。这意味着每个子节点上各自的逻辑时钟,通过HLC保持了因果序的同步(全局递增),而单个节点上局部事务的时钟可自增(局部递增)。在HLC时间戳中,可以采用三元组{pt,l,c}表示本地物理时钟(pt,三元组内的第一个元素)和混合逻辑时钟(l和c,分别三元组内的第二、三个元素)。
(1.2)在事务协调器上,事务的第一个SQL语句执行时,通过HLC算法分配快照点(获取本协调器上最新的HLC值作为快照点)。也即获取Snapshot Set=Ss={St},St是一个全局HLC分配的时间值。
(1.3)分布式事务的SQL语句执行时,随着SQL语句在子节点上执行,事务协调器将快照St下发给各个子节点。
(1.4)每个子节点上,执行基于HLC的数据项的可见性判断算法:
(1.4.1)满足读已提交规则。
(1.4.2)数据项的版本链从新到旧有序存储,遍历该版本链,找到第一个较新的且满足如下(1.4.3)中算法的数据项为止。
(1.4.3)按给定的HLC值(从事务协调器传入),假定为local_HLC,其三元组为{10,10,0},在各个子节点的版本链上进行遍历,找到和local_HLC.l值(该值为10)相同的数据版本,然后再往后读一个版本,该版本就是处于全局读一致的版本。
(1.4.4)该数据项的可见性判断算法,要求数据版本上的提交时间戳tc的数据结构,和HLC保持一致,也即要求提交时间戳tc也为基于HLC算法分配的时间戳。
(1.5)事务协调器在一个集群中可以有多个,事务协调器对应于协调节点设备,子节点对应于数据节点设备,当事务协调器只有一个时,对应于中心化的事务处理技术,当事务协调器包括多个时,对应于去中心化的事务处理技术。
(1.6)事务在提交时,从全局HLC获取提交时间戳tc,然后修改各个子节点上事务提交标识的时间戳值。
2、事务管理器
在一个集群中,事务管理器(每个物理节点的数据库实例上存在一个事务管理器)扮演着事务协调器的角色。事务协调器(协调节点设备)发起一个事务,称为父事务。在不同的子节点(数据节点设备)上执行的,称为子事务。父子事务之间,通过全局事务标识tid进行识别,每个子事务,也有自己的子事务的标识ctid,在子节点上一个事务的完整标识为{tid,ctid}。
在协调节点设备上执行目标事务T的第一个SQL语句时,为目标事务T创建快照;协调节点设备将该快照下发到目标事务T所涉及的各个数据节点设备。也即是说,在分布式数据库系统中可以采用HLC形式的快照,该HLC形式的快照由协调节点设备下发。
当目标事务T提交时,各个数据节点设备采用SDLI-M算法各自判断本节点上是否存在数据异常,也即获取本节点的异常识别信息。如果本节点的异常识别信息为存在数据异常,则回滚本地的子事务,然后发送消息通知协调节点设备的父事务,由父事务再通知其他相关数据节点设备的子事务,从而进行全局的事务回滚。
否则,如果本节点的异常识别信息为不存在(单节点的)数据异常,但无法保证其他数据节点设备上是否存在数据异常,因此协调节点设备需要在汇总各个数据节点设备上报的相关信息并上报父事务,由父事务仲裁是否存在全局的数据异常,如果存在全局的数据异常,则发送消息给各个数据节点设备,各个数据节点设备进行全局回滚;否则,则事务提交成功。
3、数据读取阶段
在一些实施例中,在DSSDLI-M算法的数据读取阶段,如果隔离级别参数<SRR(隔离级别低于SRR),每执行一次读操作,都将获取一次快照,这种情况下每次读都具有新快照则允许谓词不可重复读/幻读异常发生;否则,如果隔离级别参数≥SRR(隔离级别高于或等于SRR),仅在第一次执行读操作时获取快照,后续每次读操作均使用第一次获取的快照来读取数据,这种情况下只使用第一次的快照,能够避免谓词不可重复读/幻读异常发生。需要说明的是,此时是避免发生某一类数据异常,而不是在检测发现异常然后回滚事务,所以没有报告异常并终结事务的步骤。
在一些实施例中,当隔离级别参数≥RWC时,与上述“读写阶段事务读写集形成算法”中所涉及的基于HLC的可见性判断算法保持一致,这里不做赘述,但当隔离级别参数<RWC时,可以对前述基于HLC的可见性判断算法进行修改,使得最新的一个未提交版本可以被读取到,从而实现了RWU级别。
在一些实施例中,如果采用OCC框架,在隔离级别参数>SRR时,则对于每个事务中的第二个读操作,先从读集和写集中验证是否存在要读取的对象,如果存在,再从读写集合中获取;否则,需要从底层的存储层内获取。
这里DSSDLI-M算法的数据读取阶段与上一个实施例中SSDLI-M算法的数据读取阶段类似,这里不做赘述。
4、每个操作发生时,执行准备阶段算法
在目标事务T的每个操作(或读或写)发生时,进入准备阶段并开始做准备工作,准备阶段用于为目标事务T是否可提交做好事务并发访问控制异常验证前的准备工作。
在准备阶段中,节点设备进入临界区,遍历目标事务T的读集和写集,找出目标事务T的所有并发事务的事务标识,放入一个链表TS内进行存储,在找到后退出临界区。在内存中,每个数据项上存有曾经读写过本数据项但尚未提交的事务的事务标识。
在一些实施例中,DSSDLI-M算法与OCC算法耦合时,准备阶段的算法对应于OCC的验证阶段。
在一些实施例中,如果已有链表oldTS不为空,则把目标事务直接加入到TS中(也即令TS=oldTS+T),不再遍历目标事务的读集和写集,从而可以减少对读写集合的遍历逻辑,从而可提高事务处理效率。
DSSDLI-M算法的准备阶段算法与上述SSDLI-M算法所介绍的准备阶段算法类似,这里不做赘述。
5、子节点事务验证算法
DSSDLI-M算法所提供的子节点事务验证算法,与SSDLI-M算法所提供的改进的动边交叉与合并算法相类似,但仍存在一些差异。
在一些实施例中,DSSDLI-M算法与OCC算法耦合时,子节点事务验证算法对应于OCC的验证阶段,即当操作发生时,协调节点设备立刻开始进行验证,而不是等到进入OCC的验证阶段,这一过程称为“子节点去除”过程,此规则的目的是加快子事务的执行速度,从而提高集群系统的整体事务响应效率。
对每个数据节点设备(子节点)来说,其自身的链表TS称为cTS,在子节点上进行实时维护,没有事务发生,即维护新发生的子事务或局部事务进入cTS。每个子节点cTS的维护方式,同单机系统中描述的TS的维护方式。
在DSSDLI-M算法中,针对子节点的事务验证算法仍然包括两种不同的类型,第一种是改进的基于DLI和VS的异常检测方法,第二种是改进的基于upper的异常检测方法,下面将分类讨论。
(一)子节点上基于DLI和VS的事务验证方法
(5.1)每个操作发生时,即设定一些隶属操作级的变量的初始值:DLI=0;VS=0。
(5.2)从子节点自身的链表cTS中取出第一个事务定为TL,循环执行下述操作,直到链表为空:
(5.2.1)获取第一集合S1=DSR(T)∩DSW(TL),S1为目标事务(父事务)所对应子事务T的读集和并发事务TL的写集之间的交集。如果S1不为空,则DLI=DLI++;如果S1中某个非空元素的数据状态不同,则VS=VS++。
(5.2.2)获取第二集合S2=DSR(TL)∩DSW(T),S2为子事务T的写集和并发事务TL的读集之间的交集。如果S1不为空,则DLI=DLI++;如果S2中某个非空元素的数据状态不同,则VS=VS++。
(5.2.3)获取第三集合S3=DSW(T)∩DSW(TL),S3为子事务T的写集和并发事务TL的写集之间的交集。
(5.2.4)如果S1∪S2∪S3为空集(简化计算为:
Figure GDA0002650580260000631
Figure GDA0002650580260000632
Figure GDA0002650580260000633
),则说明TL和T不是并发事务,把TL重新加入到链表cTS的尾部。
(5.2.5)否则,S1∪S2∪S3不为空集,TL和T是并发事务,进行异常检测,一旦发现异常,回滚本地的子事务T,并立即向父事务返回目标事务的回滚消息。异常检测过程遵循下述规则:
(5.2.5.1)如果
Figure GDA0002650580260000641
在满足如下两种条件中任一项时,子节点则报告写写异常发生,循环终止。
条件一、如果隔离级别参数!=RWU(只有RWU级别不禁止脏写异常),TL没有提交完成且T.no_committed=1,存在写写冲突,数据异常类型为谓词脏写异常。
条件二、如果隔离级别参数≥SRR(SRR级别禁止丢失更新发生,所以高于或等于SRR的隔离级别均报告此异常),TL已经提交且S1∩S3不是空集,上报数据异常,数据异常类型为谓词丢失更新异常。
(5.2.5.2)否则,在
Figure GDA0002650580260000642
的条件下,如果
Figure GDA0002650580260000643
或者
Figure GDA0002650580260000644
可以分为如下三种情况进行讨论:
情况一、如果子事务T和TL构成动边交叉,则报告异常发生,循环终止。在一些实施例中,DLI≥2时,认为子事务T与TL之间构成动边交叉,此时节点设备可以根据隔离级别确定是否报告异常发生并使得循环终止。
可选地,如果隔离级别参数≥SRR(禁止谓词读偏序异常和谓词台阶式异常),且VS=1,则报告异常发生并使得循环终止,此时数据异常类型为谓词读异常,包括2个变量的谓词读偏序异常、3个及3个以上变量的谓词台阶式异常(1个变量的谓词不可重复读异常已经在数据读取阶段中被识别了,在异常检测阶段无需进行重复识别)。
可选地,如果隔离级别参数=S(禁止谓词写偏序异常和谓词锯齿波异常),且VS≥2,则报告异常发生并使得循环终止,此时数据异常类型为谓词写异常,包括2个变量的谓词写偏序异常、3个及3个以上变量的谓词锯齿波异常。
情况二、否则,如果子事务T和TL没有构成动边交叉,在隔离级别参数=S的情况下,节点设备还需要检查是否存在完整性约束,如果本事务所读写的数据违反了完整性约束,则报告异常发生并使得循环终止。
情况三、否则,如果子事务T和TL没有构成动边交叉,且符合完整性约束,那么没有任何异常,对子事务T和TL进行动边合并,设定新的事务为T-new。
在动边合并过程中,节点设备把并发事务TL的读集并入子事务T的读集,将并发事务TL的写集并入子事务T的写集;如果并发事务TL没有提交,则令T-new的目标参数T-new.no_committed++(自增1),表示合并得到的新事务中拥有某个已经提交的事务的读写集的成分;令T=T-new,用T-new给T赋值,然后执行下一次循环。
(5.2.6)如果循环结束,没有异常报告,则子事务T局部可以提交。子事务T向父事务发送本子事务T的依赖关系和无局部异常信息(也即单节点的异常识别信息)。
(5.2.7)记录本次异常检测的链表cTS,从中去除本次事务,供下次使用,使得oldTS=cTS-T,达到oldTS的实时维护。可选地,cTS里面还可以有很多合并后的逻辑事务,使得cTS的长度变小,一方面节约了存储空间,另一方面有助于加速后续每个操作的判断。
在一些实施例中,通过使用哈希表作为集合的数据结构,可以在线性时间复杂度内得到不同集合之间的交集或者并集。
(二)子节点上基于upper的事务验证方法
(5.1)每个操作发生时从子节点自身的链表cTS中取出第一个事务定为TL,分别对T.upper和TL.upper进行初始化,也即是设定一些隶属变量的初始值:T.upper=false;TL.upper=false。
(5.2)对两事务T、TL的upper值初始化完毕后,循环执行下述操作,直到链表为空:
(5.2.1)获取第一集合S1=DSR(T)∩DSW(TL),S1为目标事务(父事务)所对应子事务T的读集和并发事务TL的写集之间的交集。对于S1中的每一个变量x,若子事务T读变量x的版本≥并发事务TL写变量x的版本,则置T.upper=true;否则,置TL.upper=true。
(5.2.2)获取第二集合S2=DSR(TL)∩DSW(T),S2为子事务T的写集和并发事务TL的读集之间的交集。对于S2中的每一个变量x,若子事务T写变量x的版本>并发事务TL读变量x的版本,则置T.upper=true;否则,置TL.upper=true。
(5.2.3)获取第三集合S3=DSW(T)∩DSW(TL),S3为子事务T的写集和并发事务TL的写集之间的交集。
(5.2.4)获取第四集合S4=DSR(TL)∩DSR(T),S4为子事务T的读集和并发事务TL的读集之间的交集。对于S4中的每一个变量x,若子事务T读变量x的版本>并发事务TL读变量x的版本,则置T.upper=true;若子事务T读变量x的版本<并发事务TL读变量x的版本,则置TL.upper=true;若子事务T读变量x的版本=并发事务TL读变量x的版本,则不做任何操作。
(5.2.5)如果S1∪S2∪S3∪S4为空集(简化计算为:
Figure GDA0002650580260000661
Figure GDA0002650580260000662
Figure GDA0002650580260000663
Figure GDA0002650580260000664
),则说明TL和T不是并发事务,把TL重新加入到c链表TS的尾部。
(5.2.6)否则,S1∪S2∪S3∪S4不为空集,TL和T是并发事务,进行异常检测,一旦发现异常,回滚本地的子事务T,并立即向父事务返回目标事务的回滚消息。异常检测过程遵循下述规则:
(5.2.6.1)如果
Figure GDA0002650580260000665
在满足如下两种条件中任一项时,节点设备则报告写写异常发生,循环终止。
条件一、如果隔离级别参数!=RWU(只有RWU级别不禁止脏写异常),TL没有提交完成且T.no_committed=1,存在写写冲突,数据异常类型为谓词脏写异常。
条件二、如果隔离级别参数≥SRR(SRR级别禁止丢失更新发生,所以高于或等于SRR的隔离级别均报告此异常),TL已经提交且S1∩S3不是空集,上报数据异常,数据异常类型为谓词丢失更新异常。
(5.2.6.2)否则,在
Figure GDA0002650580260000666
的条件下,如果
Figure GDA0002650580260000667
或者
Figure GDA0002650580260000668
可以分为如下三种情况进行讨论:
情况一、如果子事务T和TL构成动边交叉,则报告异常发生,循环终止。在一些实施例中,T.upper=TL.upper=true时,认为子事务T与TL之间构成动边交叉,此时节点设备可以报告异常发生并使得循环终止。
情况二、否则,如果子事务T和TL没有构成动边交叉,在隔离级别参数=S的情况下,节点设备还需要检查是否存在完整性约束,如果本事务所读写的数据违反了完整性约束,则报告异常发生并使得循环终止。
情况三、否则,如果子事务T和TL没有构成动边交叉,且符合完整性约束,那么没有任何异常,对子事务T和TL进行动边合并,设定新的事务为T-new。
在动边合并过程中,节点设备把并发事务TL的读集并入子事务T的读集,将并发事务TL的写集并入子事务T的写集;如果并发事务TL没有提交,则令T-new的目标参数T-new.no_committed++(自增1),表示合并得到的新事务中拥有某个已经提交的事务的读写集的成分;令T=T-new,用T-new给T赋值,然后执行下一次循环。
(5.2.7)如果循环结束,没有异常报告,则子事务T局部可以提交。子事务T向父事务发送本子事务T的依赖关系和无局部异常信息(也即单节点的异常识别信息)。
(5.2.8)记录本次异常检测的链表cTS,从中去除本次事务,供下次使用,使得oldTS=cTS-T,达到oldTS的实时维护。可选地,cTS里面还可以有很多合并后的逻辑事务,使得cTS的长度变小,一方面节约了存储空间,另一方面有助于加速后续每个操作的判断。
在一些实施例中,通过使用哈希表作为集合的数据结构,可以在线性时间复杂度内得到不同集合之间的交集或者并集。
父节点(也即事务协调器、协调节点设备)在汇总各个子节点(也即数据节点设备)的依赖关系和异常识别信息之后,可以调用父节点事务验证算法进行全局异常检测,从而确定最终提交目标事务还是回滚目标事务,在本申请实施例中,提供了两种父节点事务验证算法,分别包括动边交叉合并算法和依赖关系检测算法,动边交叉合并算法可以检测出除了谓词写偏序异常外的分布式异常,而依赖关系检测算法可以检测出谓词写偏序异常,下面将分别在第6点和第7点中进行介绍。
6、父节点事务验证算法1(动边交叉合并算法)
在父事务即协调器上,构造SDLI-M算法需要的信息:父事务收集子事务的读集和写集,以及数据项/变量版本上记录的冲突的并发事务(至少一个并发事务)这些信息,然后调用SDLI-M算法,在事务的提交阶段,实现不同隔离级别的分布式事务验证,主要是验证分布式事务中的谓词读偏序、谓词台阶式、谓词写偏序、谓词锯齿波异常。
7、父节点事务验证算法2(依赖关系检测算法)
(7.1)子事务识别完毕本地节点不存在任何数据异常的情况下,在子事务准备返回消息给父事务之前,子事务需要根据依赖图,构造并发事务的依赖关系,将依赖关系返回给父事务。
在一个示例中,假设在两个物理节点Node1和Node2上,分别有四个事务T1~T4在并发执行,Node1上存在T4→T1→T3构成依赖图,Node2上存在T3→T2→T4构成依赖图。
在另一个示例中,假设在两个物理节点Node1和Node2上,分别有三个事务T1~T3在并发执行,Node1上存在T3→T1→T2构成依赖图,Node2上存在T2→T3构成依赖图。
(7.2)父事务根据各个子节点返回的多个子事务的依赖图,构造全局的依赖图,如果全局依赖图不存在环,则整个分布式事务不存在依赖环,且也没有破坏完整性约束,因此是符合可串行化S隔离级别的。
(7.3)否则,如果完整性约束被破坏,则符合快照可重复读SRR隔离级别。
(7.4)在上述(7.3)中有环的情况下:
(7.4.1)如前述,在第一个示例中,父事务收集Node1的T4→T1→T3依赖图和Node2的T3→T2→T4依赖图,合并得到全局依赖图为T4→T1→T3→T2→T4,这样首尾都是T4,因此全局依赖图中存在环,所以不可串行化,且T4事务是由两个读操作组成的,所以检测到的是谓词读偏序或谓词台阶式异常。如果隔离级别参数≥SRR(隔离级别高于或等于快照可重复读SRR),则回滚父事务及所有子事务(即回滚目标事务),报告异常。
(7.4.2)如前述,在第二个示例中,父事务收集Node1的T3→T1→T2依赖图和Node2的T2→T3依赖图,合并得到全局依赖图为T3→T1→T2→T3,这样首尾都是T3,因此全局依赖图中存在环,所以不可串行化,且T3事务分别是由读写操作组成的,所以检测到的是谓词写偏序或谓词锯齿波异常。如果隔离级别参数=S(隔离级别等于可串行化S),则回滚父事务及所有子事务(即回滚目标事务),报告异常。
(7.4.3)依赖关系检测算法只在父子事务之间传递依赖图相关信息,读写集等并不在父子事务之间传递,所以对于大结果集事务的可串行化隔离级别的实现,有较大的优势。
本申请实施例提供的DSSDLI-M算法可以适用于分布式事务型数据库系统的事务处理。在DSSDLI-M算法中,通过子节点和父节点处理隔离级别的技术,描绘了不同隔离级别和分布式事务之间的关联关系,使得分布式事务也具备多种隔离级别的能力。
上述所有可选技术方案,可以采用任意结合形成本公开的可选实施例,在此不再一一赘述。
在本申请实施例中,根据数据状态一致性模型,形式化定义了谓词类数据异常,使用谓词类数据异常的定义,统一了和谓词相关的数据异常(幻读、谓词写偏序)和非谓词类数据异常(脏读、脏写、读偏序等),揭示了各种数据异常之间的内在联系;根据本申请实施例提供的数据异常定义,提出了与传统隔离级别技术存在差异的新的、单机事务型数据库的四级隔离级别体系,并明确提出隔离级别建立的标准;提出2种适合于单机系统的并发访问控制基础算法(SDLI-M算法以及SSDLI-M算法),并结合数据异常的定义和隔离级别的定义,在算法中给出如何实现不同的隔离级别;提出分布式事务的隔离级别和单机系统的隔离级别的关联关系,并定义了分布式事务系统的四级隔离级别体系;基于分布式隔离级别和前述的基础算法,提出适合分布式事务处理的并发访问控制技术(DSSDLI-M算法),DSSDLI-M算法完整地描述了事务处理的各个阶段的具体过程,并给出若干个不同的子算法实现父事务的并发控制,指出了谓词类数据异常的集合运算与非谓词类数据异常对数据项的运算,在本质上都是保持一致的,因为其本质均为进行集合运算。
在上述提供了分布式事务隔离级别的基础上,结合动态时间戳分配(DynamicTimestamp Allocation,DTA)算法与上述实施例中的DSSDLI-M算法,可以得到基于DTA的动边交叉算法,在本申请实施例中将对基于DTA的动边交叉算法进行介绍。
其中,DTA算法是一种并发访问控制算法,其优点在于,在针对分布式事务验证分布式数据异常时,只需要搜集各个参与者节点(子节点)的子事务生命周期,其中该子事务生命周期是一个数据量很少的时间段值,而不需要从参与者节点(子节点)向协调器节点(父节点)发送大量的数据信息,因此具有更高的验证效率。
例如,和OCC机制相比,子节点的读写集合需要在父节点上参与全局验证阶段的工作,因此子节点需要将读写集合同步到父节点中,会导致网络通信次数、网络数据量增多,从而延迟事务的验证工作,而DTA机制中,子节点仅需要将子事务生命周期发送至父节点,仅涉及到少量数据的传输,而无需同步本地的整个读写集合,因此可以提升事务的验证效率。
下面将对基于DTA的动边交叉算法进行详述:
1、快照点的建立方法,全局快照点构建法
与上述实施例中DSSDLI-M算法的快照点建立方法类似,这里不做赘述。
2、事务管理器
与上述实施例中DSSDLI-M算法的事务管理器类似,这里不做赘述。
需要说明的是,两者之间的区别在于,如果单个子节点判断出本节点的异常识别信息为不存在(单节点的)数据异常,子节点在DSSDLI-M算法中实际上需要向父节点上报子节点的本地读写集合,由父节点汇总各个子节点的本地读写集合之后,构造全局读写集合并基于动边交叉与合并算法进行全局验证;而子节点在基于DTA的动边交叉算法中,无需向父节点上报子节点的本地读写集合,而是仅仅上父节点上报子事务生命周期,父事务根据各个子节点上的子事务生命周期,仲裁是否存在全局的数据异常,如果存在,则发消息给各个子节点,触发全局回滚,否则,则事务全局提交成功。其中,子事务生命周期在本质上是采用DTA技术构造出的子事务的两个逻辑生命时间戳值,包括时间戳下界lower和时间戳上界upper。
3、数据读取阶段
与上述实施例中DSSDLI-M算法的数据读取方法类似,这里不做赘述。
4、每个操作方法,准备阶段算法
与上述实施例中DSSDLI-M算法的准备阶段算法类似,这里不做赘述。
5、子节点事务验证算法
与上述实施例中DSSDLI-M算法的子节点事务验证算法类似,这里不做赘述。
需要说明的是,两者之间存在的区别在于,在子节点上验证出本地子事务不存在异常时,不管是(一)基于DLI和VS的事务验证方法中的步骤(5.2.6),还是(二)基于upper的事务验证方法中的步骤(5.2.7),都需要由子事务向父事务发送子事务的依赖关系和单节点的异常识别信息。
而在基于DTA的动边交叉算法中,子节点需要改为执行下述操作:
如果循环结束,没有异常报告,则子事务T局部可以提交。子事务T向父事务发送本子事务T的生命周期[lower,upper],可选地,只有在验证出子事务合法(也即可以局部提交)时,才应用DTA技术为本子事务T分配其逻辑上的生命周期[lower,upper]。
6、父节点事务验证算法
在父事务即协调器上,采用DTA算法,对各个参与者(子节点)发送的各个子事务生命周期[lower,upper]求交集,如果存在一个合法的交集,也即交集的时间戳下界lower小于交集的时间戳上界upper,则该目标事务可以全局提交,否则,发起全局回滚。
在本申请实施例中,在DSSDLI-M算法的基础上,结合DTA算法对事务验证阶段进行了进一步优化,能够避免在子节点与父节点之间传输数据量较大的读写集合、异常识别信息以及依赖关系,而是改为传输一个数据量很小的子事务生命周期,并基于各个子事务生命周期进行分布式异常识别,这样可以减少网络通讯开销,从而大大提升事务验证效率。
接下来,在上述各个实施例提供的适用于不同场景下的动边交叉算法的基础上,对于数据异常种类的划分技术,能够通过对事务动边交叉进行形式化定义来进行如下推演。
假设任意两个并发事务Ti与Tj,两者满足ts(Ti)<tc(Tj)且ts(Tj)<tc(Ti),且操作过相同数据项。对两者中任一事务来说,其操作的数据对象表示为Obj={Deterministicobject}or{Non-Deterministic object},即一个数据对象,要么由确定性对象诸如某个数据项X、Y等表示,要么由一个非确定性对象如一个范围谓词来表示。{Non-Deterministicobject}=={P},P表示一个谓词对象,但{Non-Deterministic object}在事务具体的读写操作发生后,所涉及的对象最终仍然是确定的。
任何一个事务T在某个数据项上能够发生两种操作op,op∈{R,W},表示操作op或者为读操作R或者为写操作W,事务的读写操作产生什么影响称为影响因子(ImpactFactors,IF),IF∈{C,A},C表示提交操作,A表示回滚操作。在一致性状态图中,每个事务的操作构成该事务在数据项上的一条连线,称为动边。
而事务之间的偏序关系(简称为偏序对),则是指:在同一个数据项X上,事务Ti的操作作用在Xk版本上,事务Tj的操作作用在Xk或Xk+1版本上,则称为top(Ti-X)<top(Tj-X),表明Ti与Tj在数据项X上存在偏序关系,具体可以划分为如下两种情况:
情况一、Tj的操作作用在Xk版本上:Tj的操作时读操作或回滚操作,如果并发事务Ti与Tj都是读操作,则两事务之间不存在偏序关系。
情况二、Tj的操作作用在Xk+1版本上:Tj的操作是写操作。
可选地,存在一种特殊偏序对,其构成结构为opi-opi(X/P)-ifi/ifj,事务的提交或回滚可能构成对之前的读写操作的影响,而ifi/ifj表示影响因子可有可无,且在操作序列中顺序可以交换。
同理,对于数据项Y来说,若存在top(Tj-Y)<top(Ti-Y),表明Ti与Tj在数据项Y上存在偏序关系。
如果上述Ti与Tj在数据项X和Y上同时存在偏序关系(上述两种条件同时成立),则称并发事务Ti与Tj存在事务动边交叉。也即是说,动边交叉的含义为:当且仅当存在事务Ti和Tj,既满足偏序Ti<Tj,又满足偏序Tj<Ti。否则,称为不存在动边交叉,不交叉则意味着仅存在一个偏序关系,或者不存在偏序关系(保持无序关系,此时对非并发事务而言属于并行操作)。
有鉴于此,数据异常能够定义为:如果并发事务Ti与Tj存在动边交叉,则在涉及到的数据项上存在数据异常。进一步地,如果X==Y,那么属于单变量的数据异常,如果X≠Y,那么属于双变量的数据异常。
在一些实施例中,事务间的操作偏序关系,也可以在不确定性对象上面构建:当存在一个谓词对象P时,相当于若干个实体对象(确定性对象)的集合,也即P={X,Y,…},且P可以是一个空集,假设在P被执行后得到数据对象中包含某个确定性对象Z,若数据项Z能够被其他事务读取,则在谓词对象P上构成一个W-R的偏序关系,由此产生了幻读、谓词写偏序等谓词类数据异常。
而对于种类纷繁的数据异常来说,异常种类是有限的,而异常个数是无限的,针对这一结论进行如下分析:
根据数据异常的定义,在被操作的数据项上,至少存在一个环,而一个环的构成,至少存在2个偏序对。那么可以推论出:1)一个异常即将形成,一定是在第一个偏序对存在的基础上,新增了一个偏序对,才能够构成环。2)一个已经存在异常的历史(History),必定至少存在构成环的两个偏序对。
由数据异常的定义可知,一个完全偏序对的构成表达式为:opi-opi(X/P)-ifi/ifj,即完全偏序对由2个操作位、2个影响因子组成,而被操作对象分为两种,一种是确定性对象,一种是非确定性对象(对应于谓词操作),所以,根据排列组合原理,可以得出完全偏序对总共存在如下表7所示的几种组合情况:
表7
Figure GDA0002650580260000731
因此,能够看出来,构成偏序对的种类是有限的,所以构成环的组合情况是有限的,因此数据异常的种类是有限的。
在一个偏序对中,有的直接构成数据异常,有的则不构成数据异常,需要和其他偏序对组合构成环才能形成数据异常。而直接构成数据异常的情况,在本质上也是形成了环,但是由于单个偏序对自身的操作和影响因子组合即可构成环,比如脏读异常:wi[X] rj[X]Ai Ci,其构成的环中存在2个偏序对,分别为wi[X] rj[X]和rj[X] Ai,前者是操作偏序对,后者是影响偏序对(语义上回滚掉了wi[X]的操作,使得读操作无效),这两个偏序对能够组合形成一个环,因此脏读是一种数据异常。
由于偏序对的构成是有限的,最多存在64种组合情况,那么一个环的构成最多包括64*64=4096种情况,但是如上述示例的脏读是可以从64种中去除的,因此自身单个偏序对已经构成数据异常,那么不会再和其他偏序对组合构成新的数据异常,同理,W-W的6种情况会构成脏写异常,同理可以从64种中去除掉,但通常情况下W-W的8种组合情况会被全部定义为脏写异常。由此可以得出结论:数据异常的种类是有限的,而这些有限的种类,即是在上述实施例之前涉及的10种谓词类数据异常。
此外,两个变量的动边交叉能够扩展为大于或等于3个变量的动边交叉,针对这一结论进行如下分析:
如果并发事务之间对数据项X存在操作偏序关系Ti→Tj,且对于数据项Y存在操作偏序关系Tj→Th,且对于数据项Z存在操作偏序关系Th→Ti。那么能够看出来,三个事务在三个变量上存在互为依存的偏序关系,即在依赖图中存在环的关系,因此不可串行化,存在数据异常。假设第三个事务Th等于Ti或者Tj中的某一个,而环的关系依然存在,则数据异常依然存在;假设第三个变量Z等于X或者T中的某一个,而环的关系依然存在,则数据异常依然存在。因此,能够看出来,两个变量的动边交叉可以扩展为大于或等于3个变量的动边交叉。
对于并发事务来说,存在两种情况,一种是直接并发,另一种是间接并发。直接并发是指操作了共同的数据项,而间接并发是指通过若干层变量作为共同变量而构成并发事务。
图11是本申请实施例提供的一种锯齿波异常的原理性示意图,请参考图11,示出了由事务操作序列构成三变量的锯齿波式数据异常。事务T1读取变量版本z0并写入变量版本x1,记为“R(z0)W(x1)”,事务T2读取变量版本y0写入变量版本z1,记为“R(y0)W(z1)”,事务T3读取变量版本x0写入变量版本y1,记为“R(x0)W(y1)”,事务T1~T3的一致性状态边如1101所示,能够看出,事务T1和T2共同操作变量z,事务T1和T3共同操作变量x,事务T3和T2共同操作了变量y,因此T1、T2、T3互为直接并发事务,在1102中示出了事务T1~T3三者之间的依赖环。
在一个示例中,请参考1103所示的四变量的锯齿波异常,此时存在间接并发的事务,比如事务T2和T4就属于间接并发关系,事务T2操作了变量x和a,事务T4操作了变量y和z,他们并没有操作共同的变量,因此并不属于直接并发,但是却因为事务T3(操作了变量a和y)和事务T1(操作了变量x和z)将两事务联系在一起,因此互为间接并发事务。
对于直接并发事务来说,通过在数据项上记录哪些事务读过、写过该数据项,则可以直接获取到作用于该变量上的所有并发事务,比如采用两个列表(List)或者两个哈希表(Hashmap)的数据结构,分别存放该数据项的读事务列表和写事务列表,当获取目标事务的直接并发事务时,只需要遍历该目标事务的读集和写集,从每个数据项的读事务列表及写事务列表中直接获取目标事务的所有直接并发事务。
对于间接并发事务来说,可以通过构建活跃事务列表和已提交事务列表来进行获取。具体地,当系统内任一事务开始时,注册到活跃事务列表中,当该任一事务结束时,从活跃事务列表中注销;当该任一事务从活跃事务列表中注销后,将正常提交的事务注册到已提交事务列表中(被回滚的事务则直接丢弃)。而在获取目标事务的间接并发事务时,先获取该目标事务的所有直接并发事务,将所有直接并发事务的读集并集设为RA,将所有直接并发事务的写集并集设为RW,接着遍历活跃事务列表和已提交事务列表中任一列表,假设该任一列表名为ListAH,从ListAH链表头中取出一个事务,把该事务的读集与RA求交集,将该事务的写集和RW求交集,如果存在任一交集不为空,说明该事务与目标事务互为间接并发事务,将该事务的读集与RA合并、写集与RW合并,以此类推,能够查询出目标事务的所有间接并发事务。
在一些实施例中,有可能某个事务Ti的读集与RA无交集、写集与RW无交集,但是通过另一个事务Tj间接与前面的目标事务构成并发事务,因此,当该事务第一次被判断为并非间接并发事务时,可以把该事务重新放入到ListAH的列表尾,待经过一轮读写集合的合并之后,重新参与前述判断,直到第二次仍然被判断为并发间接并发事务时,不再进入到ListAH的列表尾,而是确定其并非间接并发事务。
在一些实施例中,大数据场景下已提交事务列表通常很长,此时可以对已提交事务列表进行合并,比如根据列表长度,定期将参数N指定的事务数的事务合并为1个事务TT,也即是说,把最老的N个事务的读集、写集分别合并到TT的读集、写集中,然后删除前N个事务,从而可以缩小已提交事务列表的长度,提升获取间接并发事务的效率。
在一些实施例中,还可以将每个事务产生的读集和写集的并集维护在内存中,称为事务TTT,将该事务TTT的读写集合作为任何事务的间接并发事务的读写集合,同时,在事务TTT的读写集合上维护布隆过滤器,能够提高查找验证间接并发事务的效率。
在本实施例中,通过针对数据异常的定义进行分析,验证了系统内可能产生的数据异常的种类是有限的,但数据异常的数量是无限的,进一步地,提供了获取直接并发事务以及间接并发事务的方法,能够方便地获取到目标事务的所有并发事务,从而不仅可以利用动边交叉算法验证目标事务与直接并发事务之间是否存在异常,而且能够利用动边交叉算法验证目标事务与间接并发事务之间是否存在异常,能够更加全面的进行数据异常识别,避免漏判、误判的检测情况,从而提升事务验证准确率。
图12是本申请实施例提供的一种事务处理装置的结构示意图,请参考图12,该装置包括:
获取模块1201,用于根据目标事务所操作的数据集合的过滤条件,获取该目标事务的读写集合,该过滤条件用于表示该目标事务指定的该数据集合的查询范围;
第一确定模块1202,用于根据该目标事务的读写集合,确定与该目标事务所操作的数据集合重叠的至少一个并发事务;
识别模块1203,用于对该目标事务与该至少一个并发事务进行异常识别,得到该目标事务与该至少一个并发事务之间的异常识别信息;
提交模块1204,用于响应于该异常识别信息为不存在数据异常,将该至少一个并发事务与该目标事务的读写集合进行合并,提交该目标事务。
本申请实施例提供的装置,通过对于涉及到范围查询的目标事务,根据其数据集合的过滤条件也即是范围查询的谓词条件,获取到目标事务的读写集合,从而确定出读写集合存在重叠的至少一个并发事务,对目标事务与至少一个并发事务进行异常识别以获取异常识别信息,在异常识别信息指示不存在数据异常的情况下提交目标事务,这种方式能够针对涉及到范围查询的目标事务,全面检测出数据库系统内各种各样的谓词类数据异常,从而保证了数据状态的一致性,并且这种事务处理机制既不完全依赖于封锁技术也不完全依赖于依赖图技术,避免了限制数据库系统的并发度,能够提升数据库系统的事务处理效率。
在一种可能实施方式中,基于图12的装置组成,该识别模块1203包括:
识别子模块,用于对于该至少一个并发事务中任一并发事务,对该目标事务与该任一并发事务进行异常识别,得到该目标事务与该任一并发事务之间的异常识别子信息;
确定子模块,用于响应于该至少一个并发事务中包括异常识别子信息为存在数据异常的并发事务,将该异常识别信息确定为存在数据异常;否则,将该异常识别信息确定为不存在数据异常。
在一种可能实施方式中,基于图12的装置组成,该识别子模块包括:
第一获取单元,用于根据该目标事务与该任一并发事务的读写集合,获取第一集合、第二集合以及第三集合,该第一集合为该目标事务的读集与该任一并发事务的写集之间的交集,该第二集合为该目标事务的写集与该任一并发事务的读集之间的交集,该第三集合为该目标事务的写集与该任一并发事务的写集之间的交集;
第二获取单元,用于响应于该第三集合不是空集,根据该任一并发事务的提交情况获取该异常识别子信息;
第三获取单元,用于响应于该第三集合是空集且该第一集合或者该第二集合中至少一项不是空集,根据该第一集合和该第二集合获取该异常识别子信息。
在一种可能实施方式中,基于图12的装置组成,该识别子模块包括:
第一获取单元,用于根据该目标事务与该任一并发事务的读写集合,获取第一集合、第二集合、第三集合以及第四集合,该第一集合为该目标事务的读集与该任一并发事务的写集之间的交集,该第二集合为该目标事务的写集与该任一并发事务的读集之间的交集,该第三集合为该目标事务的写集与该任一并发事务的写集之间的交集,该第四集合为该目标事务的读集与该任一并发事务的读集之间的交集;
第二获取单元,用于响应于该第三集合不是空集,根据该任一并发事务的提交情况获取该异常识别子信息;
第四获取单元,用于响应于该第三集合是空集且该第一集合、该第二集合或者该第三集合中至少一项不是空集,根据该第一集合、该第二集合和该第四集合获取该异常识别子信息。
在一种可能实施方式中,该第二获取单元用于:
若该任一并发事务未提交且该目标事务的目标参数为一,将该异常识别子信息获取为存在数据异常且数据异常类型为谓词脏写异常,该目标参数用于表示该目标事务的读写集合成分所对应的已提交事务数量;
若该任一并发事务已提交且该第一集合与该第三集合之间的交集不是空集,将该异常识别子信息获取为存在数据异常且数据异常类型为谓词丢失更新异常。
在一种可能实施方式中,基于图12的装置组成,该第三获取单元包括:
第一更新子单元,用于根据该第一集合和该第二集合,更新该任一并发事务与该目标事务之间的动边交叉值和变量状态值,该动边交叉值用于表示该任一并发事务与该目标事务在数据状态矩阵中操作的不同数据项之间的线段交叉情况,该变量状态值用于表示该任一并发事务与该目标事务涉及操作到处于不同数据状态的变量情况;
第一获取子单元,用于响应于该更新后的动边交叉值大于或等于二,将该异常识别子信息获取为存在数据异常;否则,将该异常识别子信息获取为不存在数据异常。
在一种可能实施方式中,该第一更新子单元用于:
响应于该第一集合不是空集,将动边交叉值更新为已有值加一所得的数值;响应于该第一集合中存在数据状态不同的变量,将变量状态值更新为已有值加一所得的数值;
响应于该第二集合不是空集,将动边交叉值更新为已有值加一所得的数值;响应于该第二集合中存在数据状态不同的变量,将变量状态值更新为已有值加一所得的数值。
在一种可能实施方式中,基于图12的装置组成,该第四获取单元包括:
第二更新子单元,用于根据该第一集合、该第二集合和该第四集合,更新该任一并发事务的布尔型以及该目标事务的布尔型,该布尔型用于表示对应事务所构成的动边在数据状态矩阵中的垂直位置关系且该布尔型的初始值为假;
第二获取子单元,用于响应于更新后的该目标事务的布尔型和更新后的该任一并发事务的布尔型均为真,将该异常识别子信息获取为存在数据异常;否则,将该异常识别子信息获取为不存在数据异常。
在一种可能实施方式中,该第二更新子单元用于:
响应于该第一集合不是空集,对于该第一集合中任一变量,若该变量在该目标事务的读集中的版本号大于或等于该变量在该任一并发事务的写集中的版本号,将该目标事务的布尔型更新为真;否则,将该任一并发事务的布尔型更新为真;
响应于该第二集合不是空集,对于该第二集合中任一变量,若该变量在该目标事务的写集中的版本号大于该变量在该任一并发事务的读集中的版本号,将该目标事务的布尔型更新为真;否则,将该任一并发事务的布尔型更新为真;
响应于该第四集合不是空集,对于该第四集合中任一变量,若该变量在该目标事务的读集中的版本号大于该变量在该任一并发事务的读集中的版本号,将该目标事务的布尔型更新为真;若该变量在该目标事务的读集中的版本号小于该变量在该任一并发事务的读集中的版本号,将该任一并发事务的布尔型更新为真。
在一种可能实施方式中,基于图12的装置组成,该装置还包括:
第二确定模块,用于响应于该异常识别信息为存在数据异常,根据数据异常类型以及数据库系统的隔离级别,确定该目标事务的执行结果,该执行结果用于表示提交该目标事务或者回滚该目标事务。
在一种可能实施方式中,该获取模块1201用于:
响应于该过滤条件所包括的变量被读取,将被读取的变量添加至该目标事务的读集中;
响应于该过滤条件所包括的变量被写入,将被写入的变量添加至该目标事务的写集中。
上述所有可选技术方案,可以采用任意结合形成本公开的可选实施例,在此不再一一赘述。
需要说明的是:上述实施例提供的事务处理装置在处理事务时,仅以上述各功能模块的划分进行举例说明,实际应用中,可以根据需要而将上述功能分配由不同的功能模块完成,即将计算机设备的内部结构划分成不同的功能模块,以完成以上描述的全部或者部分功能。另外,上述实施例提供的事务处理装置与事务处理方法实施例属于同一构思,其具体实现过程详见事务处理方法实施例,这里不再赘述。
图13是本申请实施例提供的一种计算机设备的结构示意图。该计算机设备1300可因配置或性能不同而产生比较大的差异,可以包括一个或一个以上处理器(CentralProcessing Units,CPU)1301和一个或一个以上的存储器1302,其中,该存储器1302中存储有至少一条程序代码,该至少一条程序代码由该处理器1301加载并执行以实现上述各个实施例提供的事务处理方法。当然,该计算机设备1300还可以具有有线或无线网络接口、键盘以及输入输出接口等部件,以便进行输入输出,该计算机设备1300还可以包括其他用于实现设备功能的部件,在此不做赘述。
在示例性实施例中,还提供了一种计算机可读存储介质,例如包括至少一条程序代码的存储器,上述至少一条程序代码可由终端中的处理器执行以完成上述实施例中事务处理方法。例如,该计算机可读存储介质可以是ROM(Read-Only Memory,只读存储器)、RAM(Random-Access Memory,随机存取存储器)、CD-ROM(Compact Disc Read-Only Memory,只读光盘)、磁带、软盘和光数据存储设备等。
在示例性实施例中,还提供了一种计算机程序产品或计算机程序,该计算机程序产品或该计算机程序包括一条或多条程序代码,可选地,该一条或多条程序代码存储在计算机可读存储介质中。计算机设备的一个或多个处理器能够从计算机可读存储介质中读取该一条或多条程序代码,该一个或多个处理器执行该一条或多条程序代码,使得计算机设备能够执行上述各个实施例中事务处理方法。
本领域普通技术人员可以理解实现上述实施例的全部或部分步骤可以通过硬件来完成,也可以通过程序来指令相关的硬件完成,该程序可以存储于一种计算机可读存储介质中,上述提到的存储介质可以是只读存储器,磁盘或光盘等。
以上所述仅为本申请的可选实施例,并不用以限制本申请,凡在本申请的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本申请的保护范围之内。

Claims (12)

1.一种事务处理方法,其特征在于,所述方法包括:
根据目标事务所操作的数据集合的过滤条件,获取所述目标事务的读写集合,所述过滤条件用于表示所述目标事务指定的所述数据集合的查询范围;
根据所述目标事务的读写集合,确定与所述目标事务所操作的数据集合重叠的至少一个并发事务;
对于所述至少一个并发事务中任一并发事务,根据所述目标事务与所述任一并发事务的读写集合,获取第一集合、第二集合以及第三集合,所述第一集合为所述目标事务的读集与所述任一并发事务的写集之间的交集,所述第二集合为所述目标事务的写集与所述任一并发事务的读集之间的交集,所述第三集合为所述目标事务的写集与所述任一并发事务的写集之间的交集;
响应于所述第三集合不是空集,根据所述任一并发事务的提交情况获取异常识别子信息;
响应于所述第三集合是空集且所述第一集合或者所述第二集合中至少一项不是空集,根据所述第一集合和所述第二集合获取异常识别子信息;
响应于所述至少一个并发事务中包括异常识别子信息为存在数据异常的并发事务,将所述异常识别子信息确定为存在数据异常;否则,将所述异常识别子信息确定为不存在数据异常;
响应于所述异常识别子信息为不存在数据异常,将所述至少一个并发事务与所述目标事务的读写集合进行合并,提交所述目标事务。
2.根据权利要求1所述的方法,其特征在于,所述方法还包括:
根据所述目标事务与所述任一并发事务的读写集合,获取第一集合、第二集合、第三集合以及第四集合,所述第一集合为所述目标事务的读集与所述任一并发事务的写集之间的交集,所述第二集合为所述目标事务的写集与所述任一并发事务的读集之间的交集,所述第三集合为所述目标事务的写集与所述任一并发事务的写集之间的交集,所述第四集合为所述目标事务的读集与所述任一并发事务的读集之间的交集;
响应于所述第三集合不是空集,根据所述任一并发事务的提交情况获取异常识别子信息;
响应于所述第三集合是空集且所述第一集合、所述第二集合或者所述第四集合中至少一项不是空集,根据所述第一集合、所述第二集合和所述第四集合获取异常识别子信息。
3.根据权利要求1或2所述的方法,其特征在于,所述根据所述任一并发事务的提交情况获取异常识别子信息包括:
若所述任一并发事务未提交且所述目标事务的目标参数为一,将所述异常识别子信息获取为存在数据异常且数据异常类型为谓词脏写异常,所述目标参数用于表示所述目标事务的读写集合成分所对应的已提交事务数量;
若所述任一并发事务已提交且所述第一集合与所述第三集合之间的交集不是空集,将所述异常识别子信息获取为存在数据异常且数据异常类型为谓词丢失更新异常。
4.根据权利要求1所述的方法,其特征在于,所述根据所述第一集合和所述第二集合获取异常识别子信息包括:
根据所述第一集合和所述第二集合,更新所述任一并发事务与所述目标事务之间的动边交叉值和变量状态值,所述动边交叉值用于表示所述任一并发事务与所述目标事务在数据状态矩阵中操作的不同数据项之间的线段交叉情况,所述变量状态值用于表示所述任一并发事务与所述目标事务涉及操作到处于不同数据状态的变量情况;
响应于更新后的动边交叉值大于或等于二,将所述异常识别子信息获取为存在数据异常;否则,将所述异常识别子信息获取为不存在数据异常。
5.根据权利要求4所述的方法,其特征在于,所述根据所述第一集合和所述第二集合,更新所述任一并发事务与所述目标事务之间的动边交叉值和变量状态值包括:
响应于所述第一集合不是空集,将动边交叉值更新为已有值加一所得的数值;响应于所述第一集合中存在数据状态不同的变量,将变量状态值更新为已有值加一所得的数值;
响应于所述第二集合不是空集,将动边交叉值更新为已有值加一所得的数值;响应于所述第二集合中存在数据状态不同的变量,将变量状态值更新为已有值加一所得的数值。
6.根据权利要求2所述的方法,其特征在于,所述根据所述第一集合、所述第二集合和所述第四集合获取异常识别子信息包括:
根据所述第一集合、所述第二集合和所述第四集合,更新所述任一并发事务的布尔型以及所述目标事务的布尔型,所述布尔型用于表示对应事务所构成的动边在数据状态矩阵中的垂直位置关系且所述布尔型的初始值为假;
响应于更新后的所述目标事务的布尔型和更新后的所述任一并发事务的布尔型均为真,将所述异常识别子信息获取为存在数据异常;否则,将所述异常识别子信息获取为不存在数据异常。
7.根据权利要求6所述的方法,其特征在于,所述根据所述第一集合、所述第二集合和所述第四集合,更新所述任一并发事务的布尔型以及所述目标事务的布尔型包括:
响应于所述第一集合不是空集,对于所述第一集合中任一变量,若所述变量在所述目标事务的读集中的版本号大于或等于所述变量在所述任一并发事务的写集中的版本号,将所述目标事务的布尔型更新为真;否则,将所述任一并发事务的布尔型更新为真;
响应于所述第二集合不是空集,对于所述第二集合中任一变量,若所述变量在所述目标事务的写集中的版本号大于所述变量在所述任一并发事务的读集中的版本号,将所述目标事务的布尔型更新为真;否则,将所述任一并发事务的布尔型更新为真;
响应于所述第四集合不是空集,对于所述第四集合中任一变量,若所述变量在所述目标事务的读集中的版本号大于所述变量在所述任一并发事务的读集中的版本号,将所述目标事务的布尔型更新为真;若所述变量在所述目标事务的读集中的版本号小于所述变量在所述任一并发事务的读集中的版本号,将所述任一并发事务的布尔型更新为真。
8.根据权利要求1所述的方法,其特征在于,所述方法还包括:
响应于所述异常识别子信息为存在数据异常,根据数据异常类型以及数据库系统的隔离级别,确定所述目标事务的执行结果,所述执行结果用于表示提交所述目标事务或者回滚所述目标事务。
9.根据权利要求1所述的方法,其特征在于,所述根据目标事务所操作的数据集合的过滤条件,获取所述目标事务的读写集合包括:
响应于所述过滤条件所包括的变量被读取,将被读取的变量添加至所述目标事务的读集中;
响应于所述过滤条件所包括的变量被写入,将被写入的变量添加至所述目标事务的写集中。
10.一种事务处理装置,其特征在于,所述装置包括:
获取模块,用于根据目标事务所操作的数据集合的过滤条件,获取所述目标事务的读写集合,所述过滤条件用于表示所述目标事务指定的所述数据集合的查询范围;
第一确定模块,用于根据所述目标事务的读写集合,确定与所述目标事务所操作的数据集合重叠的至少一个并发事务;
识别模块包括识别子模块和确定子模块,所述识别子模块包括第一获取单元、第二获取单元及第三获取单元;
所述第一获取单元,用于对于所述至少一个并发事务中任一并发事务,根据所述目标事务与所述任一并发事务的读写集合,获取第一集合、第二集合以及第三集合,所述第一集合为所述目标事务的读集与所述任一并发事务的写集之间的交集,所述第二集合为所述目标事务的写集与所述任一并发事务的读集之间的交集,所述第三集合为所述目标事务的写集与所述任一并发事务的写集之间的交集;
所述第二获取单元,用于响应于所述第三集合不是空集,根据所述任一并发事务的提交情况获取异常识别子信息;
所述第三获取单元,用于响应于所述第三集合是空集且所述第一集合或者所述第二集合中至少一项不是空集,根据所述第一集合和所述第二集合获取异常识别子信息;
所述确定子模块,用于响应于所述至少一个并发事务中包括异常识别子信息为存在数据异常的并发事务,将所述异常识别子信息确定为存在数据异常;否则,将所述异常识别子信息确定为不存在数据异常;
提交模块,用于响应于所述异常识别子信息为不存在数据异常,将所述至少一个并发事务与所述目标事务的读写集合进行合并,提交所述目标事务。
11.一种计算机设备,其特征在于,所述计算机设备包括一个或多个处理器和一个或多个存储器,所述一个或多个存储器中存储有至少一条程序代码,所述至少一条程序代码由所述一个或多个处理器加载并执行以实现如权利要求1至权利要求9任一项所述的事务处理方法所执行的操作。
12.一种存储介质,其特征在于,所述存储介质中存储有至少一条程序代码,所述至少一条程序代码由处理器加载并执行以实现如权利要求1至权利要求9任一项所述的事务处理方法所执行的操作。
CN202010628597.XA 2020-07-02 2020-07-02 事务处理方法、装置、计算机设备及存储介质 Active CN111736964B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202010628597.XA CN111736964B (zh) 2020-07-02 2020-07-02 事务处理方法、装置、计算机设备及存储介质

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202010628597.XA CN111736964B (zh) 2020-07-02 2020-07-02 事务处理方法、装置、计算机设备及存储介质

Publications (2)

Publication Number Publication Date
CN111736964A CN111736964A (zh) 2020-10-02
CN111736964B true CN111736964B (zh) 2021-08-06

Family

ID=72652568

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202010628597.XA Active CN111736964B (zh) 2020-07-02 2020-07-02 事务处理方法、装置、计算机设备及存储介质

Country Status (1)

Country Link
CN (1) CN111736964B (zh)

Families Citing this family (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111708615B (zh) 2020-05-20 2021-10-29 腾讯科技(深圳)有限公司 事务处理方法、装置、计算机设备及存储介质
CN112069196B (zh) * 2020-11-12 2021-03-23 腾讯科技(深圳)有限公司 基于数据库的数据处理方法、装置、设备及可读存储介质
CN112463311B (zh) * 2021-01-28 2021-06-08 腾讯科技(深圳)有限公司 事务处理方法、装置、计算机设备及存储介质
CN112559637B (zh) * 2021-02-19 2021-06-18 腾讯科技(深圳)有限公司 基于分布式存储的数据处理方法、装置、设备以及介质
CN115098228B (zh) * 2021-05-19 2023-04-14 腾讯科技(深圳)有限公司 事务处理方法、装置、计算机设备及存储介质
CN113569083B (zh) * 2021-06-17 2023-11-03 南京大学 基于数据溯源模型的智能音箱本地端数字取证系统及方法
CN115114374B (zh) * 2022-06-27 2023-03-31 腾讯科技(深圳)有限公司 事务执行方法、装置、计算设备及存储介质

Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN110019468A (zh) * 2017-12-05 2019-07-16 华为技术有限公司 一种数据库系统及数据库访问方法
CN111159252A (zh) * 2019-12-27 2020-05-15 腾讯科技(深圳)有限公司 事务执行方法、装置、计算机设备及存储介质
CN111198872A (zh) * 2020-01-06 2020-05-26 中科驭数(北京)科技有限公司 数据库处理事务的方法及装置

Family Cites Families (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101719116B (zh) * 2009-12-03 2011-09-28 浙江大学 基于异常处理的事务存储访问机制的实现方法及所用系统
CN102214247B (zh) * 2011-07-21 2013-06-12 山东地纬计算机软件有限公司 一种支持并发的文件事务方法
US10282364B2 (en) * 2015-04-28 2019-05-07 Microsoft Technology Licensing, Llc. Transactional replicator
CN105786595B (zh) * 2016-02-29 2019-04-23 浪潮通用软件有限公司 一种两段式提交的事务控制方法
US10896169B2 (en) * 2017-05-12 2021-01-19 International Business Machines Corporation Distributed system, computer program product and method
CN111209093B (zh) * 2020-01-16 2022-07-22 华东师范大学 一种分布式数据库系统中分布式事务的处理方法

Patent Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN110019468A (zh) * 2017-12-05 2019-07-16 华为技术有限公司 一种数据库系统及数据库访问方法
CN111159252A (zh) * 2019-12-27 2020-05-15 腾讯科技(深圳)有限公司 事务执行方法、装置、计算机设备及存储介质
CN111198872A (zh) * 2020-01-06 2020-05-26 中科驭数(北京)科技有限公司 数据库处理事务的方法及装置

Also Published As

Publication number Publication date
CN111736964A (zh) 2020-10-02

Similar Documents

Publication Publication Date Title
CN111736964B (zh) 事务处理方法、装置、计算机设备及存储介质
CN112231071B (zh) 事务处理方法、装置、计算机设备及存储介质
Amiri et al. Parblockchain: Leveraging transaction parallelism in permissioned blockchain systems
CN111338766B (zh) 事务处理方法、装置、计算机设备及存储介质
CN111143389B (zh) 事务执行方法、装置、计算机设备及存储介质
WO2022161308A1 (zh) 事务处理方法、装置、计算机设备及存储介质
CN111444027B (zh) 事务处理方法、装置、计算机设备及存储介质
CN111597015B (zh) 事务处理方法、装置、计算机设备及存储介质
Turcu et al. Automated data partitioning for highly scalable and strongly consistent transactions
Moniz et al. Blotter: Low latency transactions for geo-replicated storage
Maiyya et al. Unifying consensus and atomic commitment for effective cloud data management
Amiri et al. Permissioned blockchains: Properties, techniques and applications
Margara et al. A model and survey of distributed data-intensive systems
Meir et al. Lockless transaction isolation in hyperledger fabric
Krechowicz et al. Highly scalable distributed architecture for NoSQL datastore supporting strong consistency
WO2023124242A1 (zh) 事务执行方法、装置、设备和存储介质
Wu et al. FabricETP: A high-throughput blockchain optimization solution for resolving concurrent conflicting transactions
CN115098228B (zh) 事务处理方法、装置、计算机设备及存储介质
Papanikolaou Distributed algorithms for skyline computation using apache spark
Qadah et al. Highly Available Queue-oriented Speculative Transaction Processing
Koloniari et al. Transaction management for cloud-based graph databases
Dragoni A model-based methodology to define data-intensive architecture
Younas et al. A new model for testing CRUD operations in a NoSQL database
Faleiro et al. CScale–A Programming Model for Scalable and Reliable Distributed Applications
CN117112692A (zh) 一种混合型分布式图数据存储与计算方法

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
REG Reference to a national code

Ref country code: HK

Ref legal event code: DE

Ref document number: 40030108

Country of ref document: HK

SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant