具有快照隔离的基于约束的一致性的制作方法

文档序号:6547424阅读:226来源:国知局
具有快照隔离的基于约束的一致性的制作方法
【专利摘要】本发明公开了具有快照隔离的基于约束的一致性。通过识别对于正确应用行为而言需要满足的约束来提供并发原子事务的高效处理。利用这些所识别的约束,用于事务的提交处理于是可以引用约束,以查看在所述约束的情况下提交当前事务是否引起问题。如果存在与所述约束的冲突,则事务中止。如果不存在与所述约束的冲突,则事务提交。
【专利说明】具有快照隔离的基于约束的一致性

【技术领域】
[0001]本发明涉及事务处理。

【背景技术】
[0002]原子事务经常用于简化并发和容错编程。如果事务是不可分的,则其为原子的,以使得用以执行事务的尝试可能仅有两种可能的结果:1)事务的所有部分发生(事务提交);或者2)事务的各部分不发生(事务中止)。因此,对于原子事务而言,不可能有事务的部分执行发生。例如,如果事务是将资金从一个账户转移到另一账户,则高度期望该事务是原子的,以避免信贷应用于一个账户而在另一账户中没有对应借记的可能性(或反之亦然)。在更一般的编程情况下,由于原子事物而得到类似的优点。
[0003]可以识别用于提供原子事务的两种基本方法:1)就地更新(in-place update)和
2)阴影拷贝(shadow copy)。前者通常通过锁定以防止并发更新以及撤销(undo)日志来实现,以能够在事务中止的情况下撤销改变。这还可以替代使用锁定而通过如果另一事务写入该事务正在写入的数据(所谓的写入-写入冲突)或写入该事务正在读取的数据(所谓的读取-写入冲突)则中止事务来开放式地实现。
[0004]历史上直到最近,考虑到大多数事务数据已经是基于盘的,就地更新因为保持盘布局的益处而受到偏爱。然而,考虑到在很多应用中读取比写入占优势,读取锁定是明显的开销。此外,读取锁定数据意味着对于被锁定数据的更新被延迟,这实际意味着如果对应的真实世界值在其被锁定的时间期间改变,则其潜在地与真实世界不一致而结束。在某种意义上,这意味着其对于实现内部一致性的关注可能导致与外部环境的不一致性。考虑到读取-写入冲突的普遍性(prevalence),就地更新的开放式形式可能由于过度的中止率而受损。
[0005]在移动到存储器中的数据库的情况下,阴影拷贝方法变得比以前更有吸引力。在此,更新事务使得数据的拷贝被更新、作出修改并且然后原子地更新对该数据的根引用(或指针)以引用新的(先前阴影)拷贝。进一步采用该方法,事务可以从甚至其恰正在读取的数据的快照(即不可变的拷贝)执行。该方法被称为快照隔离(SI)。该方法提供具有不由于就地更新事务的读取-写入冲突而受损的附加明显益处的常规串行化事务的大多数性质,其中就地更新事务的读取-写入冲突可能招致明显的锁定开销或者在开放式实现的情况下增加中止率。
[0006]阴影拷贝在分布式实现中可能是有吸引力的,因为其经常需要在处理执行事务时复制数据,由此提供数据的拷贝或快照以提供高效的本地存取。在此情况下,SI的拷贝开销由于保存该拷贝的存取提供本地处理而被有效地消除,或者反过来,本地拷贝的创建已经有效地负担了 SI事务机制所要求的快照的成本。该本地拷贝还可以减少处理面临包含状态的主拷贝的处理的失效和重启,因为其可以利用其本地快照而继续操作。
[0007]遗憾的是,在所有的执行产生好像以某种顺序的次序被执行那样的相同结果的意义上,SI不提供顺序一致性(或者可串行化(serializability),如其在数据库世界中被描述的那样)。因为所谓的写入偏移问题,所以出现折中行为。可以通过考虑期待事务应用被保持的简单断言约束来图解该问题。例如,考虑断言约束:
39 > b + c;
其中,分离的事务Tb和Tc可以分别更新b和C。如果b和C初始为10,则Tb可以将b更新为20,将c的快照看作10,而Tc可以将c更新为20,类似地将b的快照看作10。因为没有写入-写入冲突,所以这两个事务可以均在SI模型中并发地提交,而这样做引起约束被违反。
[0008]已经对该问题提出了各种解决方案,包括确保SI事务的严格的可串行化,但这些或是在事务处理自身上导致过度开销或是由于将事务的中止率增加得远高于严格所需而导致过度开销。
[0009]所需要的是一种在保持SI事务的应用和实现益处的同时确保正确应用行为的手段。


【发明内容】

[0010]本方法基于识别对于正确应用行为而言需要被满足的约束。在这些约束被识别的情况下,用于事务的提交处理可以然后引用约束并且引用并发更新以查看提交当前事务是否在有约束的情况下引起问题。如果存在与约束的冲突,则事务中止。如果不存在与约束的冲突,则事务提交。
[0011]与常规的快照隔离相比,因为本方法解决了常规快照隔离的写入偏移问题,所以其提供优良的语义。
[0012]与对于SI (例如可串行化的SI)的写入偏移问题的常规修复相比,本方法可以提供更高的效率(例如减少的事务开销和/或更少的不必要事务中止)。例如,如果对数据的要求被表达为可以作为提交处理的一部分而被检查的约束,则可以在不中止事务的情况下解决很多明显的写入-写入冲突。

【专利附图】

【附图说明】
[0013]图1示出若干事务的例示性时间线。
[0014]图2示出根据并发更新来更新当前事务的快照以提供被合并的快照的示例。
[0015]图3示出根据当前事务所执行的操作来更新快照的示例。
[0016]图4A提供事务、断言约束和更新约束的例示性示例。
[0017]图4B是与图4A的示例有关的图。
[0018]图5示出按轮次执行事务处理的示例。

【具体实施方式】
[0019]介绍
我们通过以下操作来提供具有快照隔离(SI)事务的正确应用行为:
1)明确地指定对隐含数据模型的约束;
2)如果数据模型保持这些约束,则设计应用处理是正确的;
3)作为事务提交处理的一部分对约束进行检查以确保每个约束由事务保持,或者另外如果这并未被实现则中止事务。
[0020]如果所有这样的约束被明确地指定,则基础架构可以确保违反这样的约束的事务被中止。
[0021]我们认为,如下面那样,应用可以被设计为如果对于其数据模型所要求的约束被保持则正确地操作。首先,每个应用事务被实现为读取并且写入应用状态的一系列指令,即其数据模型。在所有的事务模型中,每个应用事务除了其通过该数据模型的交互之外独立并且并发地执行。该应用处理关于用于其正确执行的数据模型作出一定的假设。可以按照在应用事务的执行期间数据模型的将要为真的约束、声明来捕获这些假设。因此,如果应用相对于这些约束是在过程上是正确的,并且数据模型约束在每个事务的执行期间为真,则应用正确地执行。
[0022]要求可串行化的常规方法自身并不确保应用特定的约束成立。其仅仅是确保如果事务的命令式(imperative)代码当被执行为串行事务时维持约束,则因为执行是可串行化的,即等同于串行执行,所以该代码在由多个事务并发地执行时也维持约束的(笨拙)方式。
[0023]与此对比,在本工作中,约束被明确地声明,并且然后运用约束特定的手段以确保它们成立,而不是强加这种通用次序要求(这经常相当于对于写入偏移的问题的过度破坏的解决方案)。
[0024]在一些情况下,输入源代码包括约束的说明。在这样的情况下,可以容易地自动生成对应的约束检查代码。如果输入源代码不包括其约束的明确说明,则经由自动程序分析自动生成对应的约束检查代码可以是可能的。然而,实际上,很有可能用户将需要为不具有明确约束的输入源代码提供约束检查代码。
[0025]利用SI事务确保数据模型约束通过考虑对于写入偏移的常规解决方案,可以展示出使用SI来确保约束成立的可行性。
[0026]常规解决方案有效地将每个约束具体化(materialize)为由更新该约束中的变量的任何事务所更新的变量。例如,使用更早些的示例,将会存在比如具有所构造的名称“约束一(39>b+c)”的变量,其作为更新b或c的部分而递增。结果,影响同一约束的任意两个并发事务将具有写入-写入冲突,并且它们中的至少一个将被SI事务机制中止。因此,对于事务机制而言可行的是通过这种构造来自动确保这些约束在每个事务期间成立。
[0027]注意,在很多情况下,该方法导致不必要的中止。例如,继续我们更早些的示例,如果并发地更新a和b而它们的和仍然还小于39,则即使将二者都提交也仍将维持约束,但因为在约束变量上的写入-写入冲突,所以事务中的一个被不必要地中止。此外,在最坏的情况下,这些SI事务的写入集合可能被扩展从而所有事务具有重叠的写入集合,强制这些事务的顺序执行。实际上,这种构造扩展写入集合以补偿读取-写入冲突的检测的缺失。
[0028]本方法因此提供一种提交事务的方法,该方法基于约束的实际语义而允许更大的并发和更少的中止(与在所有情况下宣称写入-写入冲突相反)。
[0029]基本的想法是使这些约束的知识在提交时间可用,以识别在该时间的任意冲突,尝试解决这些冲突,并且在假设事务不会出于其它原因(诸如资源限制)而被中止的情况下,只有这些冲突不能被解决才中止。
[0030]在对该方法进一步详述之前,我们首先澄清一些术语。并发事务是在当前事务的开始时间之后并且在该事务的目标提交时间之前提交给数据模型的事务。并发更新是这样的并发事务所执行的更新。图1提供一些示例以图解该术语。在此,TO是在时间线上示出的当前事务。事务Tl和T2与TO并发,而事务T3和T4并不与TO并发。注意,并发的定义与哪个事务被指明为当前事务有关。例如,如果T2被当作是当前事务,则TO并不与T2并发。
[0031]更具体地说,当前事务TO具有开始时间t0s和当前目标提交时间t0e。类似地,事务T1、T2、T3和Τ4具有对应的开始时间tls、t2s、t3s和t4s,并且具有对应的结束时间tle、七26336和t4e(此时事务要么提交要么中止)。因为t0s < tle < t0e并且t0s < t2e < t0e,所以Tl和T2与当前事务TO并发。因此,tle和t2e是在当前开始时间(tcs)之后并且在当前目标提交时间()之前的中间时间。
[0032]示例性事务处理方法包括下面的步骤:
I)提供与数据模型中的数据有关的约束集合。
[0033]2)执行至少两个事务,其中,所述事务中的每一个具有对应的开始时间,并且依赖于从开始时间之时起所述数据模型的一部分或全部的对应快照。在图1上,这些快照被标记为S0、S1、S2、S3和S4,分别与事务T0、T1、T2、T3和Τ4对应。
[0034]3)针对如上面所定义的当前事务以及一个或更多个并发事务,执行提交处理检查,提交处理检查自动确定是否可以与至少来自a)当前事务的快照jPb)并发事务对数据模型所作的改变这两者的约束集合一致地提交当前事务。
[0035]4)如果能够使得当前事物与所述约束集合一致,则自动地提交当前事物。以及 5)如果不能使得当前事物与所述约束集合一致,则自动地中止当前事物。在此,步骤4
和5依赖于步骤3的提交处理检查的结果。
[0036]断言约束和读取-写入集合
“断言”约束检查给定的条件为真,并且如果并非如此,则强制中止事务。
[0037]在该方法中,对照其它并发更新来检查每个断言约束,如果使用当前值(即在这些更新之后)以及在当前事务中被更新的那些值违反断言约束,则中止当前事务。用于断言约束的读取集合是需要被读取以估计约束表达式(即确定其是否为真)的变量集合。如果当前事务已经写入被指定为约束的一部分的至少一个变量(X),则检查于是需要确定任何并发事务是否已经改变与约束关联的任何其它变量。这可以被当作是读取-写入冲突检查。如果一个或更多个这样的变量已经被并发事务修改,则约束检查需要利用这些新提交的值以及X的被更新的但未提交的值来重新估计约束,以验证约束仍然成立。
[0038]实际上,可以看到,在当前事物的快照被提交以生成被合并的快照之前,将并发更新应用于当前事务的快照。对照数据模型状态的这种被合并的快照来检查断言约束。图2示出该情况的示例。在此,事务Tl的并发更新被应用于初始快照SO以生成第一被合并的快照Sml(其可以替代初始快照S0)。稍后,事务T2的并发更新被应用于被合并的快照Sml以生成第二被合并的快照Sm2(其可以替代更早的被合并的快照Sml)。针对当前事务TO的提交处理检查可以引用快照Sm2,并且由此包括来自事务Tl和T2的并发更新的效果。提交处理检查可以包括使用被合并的快照重新估计断言约束。如果生成若干个被合并的快照,则运用最新近的快照。为了让图解清楚,图2的示例示出分离的被合并的快照。替换地,在提交处理的时间生成单个被合并的快照,其包括对从如上面那样的约束确定的读取集合中的变量的所有并发更新的效果。对于任一种替换,这样的被合并的快照通过更新更早的快照来把被提交的归因于并发事物的改变考虑在内,而不使当前事务由于并发事务而面临未被提交的改变。
[0039]图3示出关于该主题的变形,其中,当前事务TO根据其执行的操作来更新其快照,以提供被更新的快照用于提交处理检查。在该示例中,当前事务TO将操作01、02和03按顺序应用于初始快照S0,以分别提供被更新的快照S1、S2和S3。提交处理检查可以引用被更新的快照S3以确定是否提交当前事务T0。如果TO被中止,则在被更新的快照S1、S2和S3中作出的改变从不会得以被提交到主数据模型,由此维持原子事务的期望的性质。为了让图解清楚,图3的示例示出分离的被更新的快照。替换地,在提交处理的时间生成单个被更新的快照,其包括当前事务的所有操作的效果。
[0040]可以从重做(redo)日志确定并发更新,如常规实践那样。
[0041]在实施例中,可以通过将当前事务快照与当前所提交的数据模型状态关于指示并发更新的差异(由当前事务中的更新引起的差异除外)进行比较来确定并发更新。
[0042]在实施例中,可以通过将当前所提交的数据模型状态与从当前事务的开始时间之时起所提交的状态的未被修改的快照关于指示并发更新的差异进行比较,从而确定并发更新。
[0043]在实施例中,如更早些所描述的那样,可以通过按每个约束对变量进行具体化并且进行更新来检测并发的潜在冲突更新,但是如上面那样使用在这样的约束变量上的写入-写入冲突的指示来触发约束解决处理,而不是立即中止当前事务。
[0044]利用上面的方法,两个并发事务可以更新影响同一约束并且仍然提交的两个属性。例如,继续更早些的示例,如果更新b的事务Tb与更新c的当前事务Tc并发地运行,则在Tc的提交处理时,检测b的并发更新而触发约束的重新估计。如果被更新的b和c的值仍然小于上限39,则当前事务可以提交,否则其被中止。因此,在该方法中,只有在逻辑上必须由断言约束来中止事务时才这样做。
[0045]在实施例中,事务机制可以针对一些约束选择该重新估计约束的方法,而对于其它约束使用常规的“约束变量”方法(例如,如果约束对于提交处理而言被认为执行起来太昂贵或困难)。在所期待的情况下,大多数约束是相对简单的。因此,与单纯使用常规方法相比,仅将该约束分析方法应用于简单的约束、否则仍借助于常规的“约束变量”的构造的实施例应会在使开发复杂度最小化的同时提供明显的性能改进。
[0046]更新约束
另一类别的约束是“更新约束”,其中,某个属性的值是由约束来确定的,并且因此当约束的参数值改变时被更新。更新约束的示例是“等式约束”,其中所确定的属性被指定为等同于某个表达式。例如:al = a0 + I;
意思是al被约束为等同于a0加I的值。利用更新约束,实现引起所确定的属性(在此情况下即al)在约束的自变量(在此情况下即a0)改变时被更新。
[0047]在2008 年 05 月 21 日提交的标题为 “Notificat1n-based constraint settranslat1n to imperative execut1n”、案卷号 0TS-102/US 的美国专利申请 12/154,399中描述了更新约束的实现,通过整体引用该专利申请而将其并入于此,并且在下文中将其称为0TS-102。与此对比,常规SQL完整性约束(诸如断言)只是检查相关联的表达式在事务的提交期间是否成立,并且如果不成立则中止事务。
[0048]图4A到图4B提供断言约束与更新约束之间的差异的简单示例。在图4A上考虑了三个事务。事务Tl是将资金从账户I转移到账户2,事务T2是账户I中的利息增加额,并且事务T3是账户2中的利息增加额。断言约束Cl和C2分别用于防止透支账户I和账户2。更新约束C3和C4对于当余额改变时针对账户I和账户2更新利息利率(如果余额〈1000则无利息,如果余额>=1000则支付利息)有益。
[0049]图4B示出用于图4A的示例的约束(左侧)和数据模型成员(右侧)的维恩图。在此,402是所有约束的集合,404是与当前事务Tl有关的所有约束的集合,并且406是作为更新约束的约束404的子集。在右侧,412是所有数据模型成员的集合,414是受当前事务Tl影响的所有数据模型成员的集合,并且416是因为Tl的相关联的更新约束所以受Tl影响的数据模型成员的集合。将受当前事务的更新约束影响的数据模型成员称作为“目标成员”是方便的。
[0050]在该示例中,我们看到事务Tl直接影响数据元素余额I和余额2(S卩,存在资金的转移)。然而,因为更新约束的原因,所以目标成员利率I和利率2也间接地受提交事务Tl影响。这可以被当作是用于利用相关的约束集合来检查提交当前事务的第二(以及更高)阶效果的一致性的机制。因此,提交处理检查可以包括:1)针对当前事务确定数据模型的将要由于提交当前事务而作为更新约束的结果被更新的目标成员;以及2)确定提交当前事务以及根据更新约束来更新目标成员是否与约束集合一致。
[0051]在本工作中,所确定的属性可以被自动更新并且在提交事务之前添加到写入集合,或作为提交事务的一部分。因此,在提交时,事务自动确保该约束被保持。如果存在未解决的写入-写入冲突,则中止事务,即使由这样的约束解决方案引起写入中的一个或更多个也如此。
[0052]在实施例中,指定断言约束和更新约束,以使得更新约束不会引起断言约束被违反。可以通过具有排除这样的违反的断言约束来实现这种情况。例如,如果如在更早的示例中那样由更新约束来确定变量al,并且通过断言约束al < 100将al约束为小于100,则该断言约束被断言约束a0 < 99替代,从而更新约束从不会引起断言违反。
[0053]在实施例中,当使用被合并的快照在提交时间(重新)估计更新约束时,独立于由于相关联的更新约束的对所确定属性的冲突写入来提交事务。因为所确定的属性由约束和被合并的快照确定,而并非直接通过任何事务的动作来确定,所以该情况得以保证。
[0054]在实施例中,例如,如在0TS-102中所指定的那样,针对数据模型所指定的约束被转译为单个触发约束的组集而作为数据模型的编译和实例的一部分。因此,当更新被事务执行并且被应用于数据模型时,与每个被触发的约束关联的命令式过程被调用,并且由这些约束执行的任何写入被追踪为事务的一部分。特别地,并发更新被在逻辑上应用于当前快照,这意味着这些更新也能够引起更新约束的触发,但是然后利用当前所提交的状态加上要作为当前事务的一部分被提交的状态来估计所有这些约束,以确保约束在最终(要被提交的)状态下成立。如上面指示的那样,实际上,通常优选的是将当前快照的所有修改推迟到直到当前事务的提交处理(与在每次并发更新之后就更新快照相反)。如果并发更新影响更新约束,则可以通过在当前事务的提交处理期间合并该并发更新来重新触发该更新约束处理。
[0055]由约束操控过程进行的写入可以触发其它约束,这能够触发进一步的写入。确保这种序列最终完成是应用程序员在开发约束说明中的职责。实际上,序列通常很短,诸如一个或两个触发级别。
[0056]在作为约束处理的一部分的失效的情况下,中止事务并且不作出对数据模型的改变。
[0057]在分布式的实施例中,数据模型实例可以被执行为与执行代码的处理分离的“sysdb”处理,以执行事务的动作,后者的处理被称为“代理”。当这样的代理完成事务执行时,其将该事实传送给sysdb处理,sysdb处理然后操控提交处理。如果整个数据模型由单个sysdb处理保持,则其可以执行所有约束的提交处理作为本地动作,因此使得与要求分布式的通信的设计相比是高效的。
[0058]在跨多个sysdb处理对数据模型进行分区的实施例中,约束生成的写入可以应用于此前在该事务中未牵涉的sysdb处理中所存储的状态。在此情况下,当前事务被扩展为包括该附加的sysdb处理。
[0059]在实施例中,sysdb处理将事务的改变以日志记录到数据模型(即重做(redo)或预写式(write-ahead)日志),并且实际上还未将这些改变应用于数据模型实例。在初始准备提交期间,其然后将这些日志记录的改变应用于数据模型实例,引起约束生成附加的写入。这些附加的写入由日志记录机制捕获,日志记录机制检测对于数据模型的改变,以用于将这些改变存留到次级存储件和/或将这些改变传送到数据模型的其它拷贝(诸如分离处理所提供的备份拷贝(被提供以允许在失效的情况下的快速恢复))。应用这些日志记录的改变还能够调用代码以检查任何受影响的断言约束。如果任何这些断言约束失效,则然后可以中止事务。注意,在该实施例中,在应用这些日志记录的改变期间该sysdb处理中的状态表示日志中直到该点的被合并的快照。如果断言约束受日志中的多个改变影响,则在最后的这样的改变提供与所述断言约束有关的完整的被合并的快照状态。因此,总是在用于当前事务的状态的最终的被合并的快照上有效地估计断言约束。
[0060]在该约束执行已经完成之后,如果事务仍然能够提交(即作为约束检查或动作的结果,还没有失效),则以常规方式提交事务状态,典型地在事务提交的指示的情况下将更新刷新到重做日志。如果在提交处理期间强制中止事务,则可以根据撤销日志撤销对sysdb状态的改变,如本领域中熟知的那样。
[0061]在写入-写入冲突被检测为该提交处理的一部分的情况下,提交处理尝试解决写入-写入冲突,如以下所描述那样,否则如果其不能解决写入-写入冲突,则中止事务。
[0062]写入-写入冲突解决方案
在实施例中,在提交时间元数据关于数据模型中已经由该事务更新的属性是可用的,元数据描述这些属性的类别、类型和/或语义。然后,事务提交机制关于写入-写入冲突考查相关联的属性、属性值以及相关联的元数据,以确定是否存在可能的解决方案。
[0063]作为一种情况,元数据可以指示其上存在当前事务与并发事务之间的写入-写入冲突的属性ai是计数器。在这样的情况下,提交处理可以从当前事务确定要使用的增量。用于当前事务的提交处理于是可以将该增量应用于并发事务已经提交的ai的值,以确定用于ai的正确最终值。实质上,先前所提交的写入和当前事务两者都使计数器递增,从而倘若当前事务以使两个增量都维持的值来进行提交,则写入-写入冲突并不需要使当前事务中止。如果多个并发事务已经更新计数器ai,则用于当前事务的提交处理将当前事务增量应用于最新近提交的并发更新。
[0064]例如,如果计数器具有在用于当前事务的最初快照中为3的先前值并且现在其为4,则当前事务已经使计数器递增I。然后,如果因为并发增量所以当前所提交的计数器的值是7,则当前事务以7+1=8的值进行提交,从而当前事务的效果(即递增I)与其它并发更新的效果合并。
[0065]作为另一情况,如果属性不是计数器,则如果并发写入和当前事务写入正将属性写入为相同的值,那么可以在没有进一步的动作的情况下认为写入-写入冲突被解决。
[0066]作为又一情况,如果元数据指示写入-写入冲突出现在具有被定义的默认值或空值的映射数据结构上,则提交处理可以确定并发写入是否将录入项改变为默认值,这指示其正有效地将该录入项从映射删除而当前事务正将同一录入项写入为非空值。在此情况下,假如更早的提交事务有效地删除录入项并且当前事务添加具有相同的键但不同值的录入项,则由当前事务所写入的值可以越过所提交的值。
[0067]在一些情况情况下,用于录入项的键是被生成或分配的值,从而当前事务可以只选择不与并发更新冲突的用于录入项的不同的键,由此解决写入-写入冲突。
[0068]另一情况是并发事务将元素写入到与当前事务写入到的队列相同的队列的末尾。可以通过简单地在(多个)并发事务所入队的(多个)元素之后附加当前事务的元素来解决该情况。
[0069]在实施例中,属性可以具有与其关联的写入冲突解决过程,写入冲突解决过程可以作出上面指示的处理序列中的一个或替换地作出解决写入-写入冲突的某种应用特定处理。作为后者的例示性示例,该过程可以确定写入-写入冲突作为并发事务分配一些共享资源的结果而出现,然而该并发事务表示更低的优先级处理或用户。在此情况下,可以从该更低优先级处理回收资源,作为结果可能运行补偿事务,并且该写入-写入冲突然后由于不允许当前事务提交的原因而被去除。
[0070]总之,约束可能引起与并发事务冲突的写入,然而也可以通过基于与受影响的属性关联的元数据的提交处理来解决与并发事务冲突的写入。可以如上面那样利用合适的约束来操控计数器,即计数器被约束为等于某个特定事件的数目。作为另一示例,包含组集中的这些值的平均值的属性可能受影响,并且因此由更新该组集中的值的两个并发事务来写入。然而,通过利用先前所提交的值来重新计算当前事务中的平均,被改正的值消除了对于由其初始的写入-写入冲突来引起当前事务的中止的需要。
[0071 ] 考虑应用的一般结构,应用数据模型普遍地包括原始数据输入和(内部)推导的数据这两者。因为原始数据输入通常来源于特定的输入装置,所以其自身不导致写入-写入冲突。例如,来自传感器I的原始数据输入不盖写来自传感器2的原始数据输入。此外,因为存在对从传感器I进行读取负责的一个处理,所以来自传感器I的更新原本就是顺序的并且不是彼此并发的。
[0072]与此对比,经常可以按照确定被推导的数据的值的等式约束(或类似的构造)来指定推导出的数据。因此,原始数据的两个并发更新(例如来自传感器I和2)可能关于所推导的数据引起写入-写入冲突(诸如上面的求和),并且可以通过允许基于被合并的快照的约束的重新计算来解决这些写入-写入冲突。
[0073]使用这些技术,在应用中即使不是在所有情况下也可以在很多情况下解决写入-写入冲突,明显减少中止率,并且由此提供比完全串行化执行的常规实现更好的性能。
[0074]异步约束
在实施例中,能够通过标识所确定的属性来将更新约束指明为是异步的。例如,先前的约束可以被指定为:al' next = a0 + I;
以指示对al的更新可以关于对aO的更新异步地发生。在此情况下,如果由分离的sysdb处理保持al,则在最初的sysdb处理上的提交处理发起分离的“补偿”事务以在保持al的sysdb处理上执行,而不是将其处理为当前事务的一部分。结果,当前事务不需要被扩展为包括该更新。其也不需要等待对al的该更新完成。
[0075]在补偿事务不能够提交的情况下,可以存在针对该情况指定的进一步的动作,其可以包括用以将改变复原到aO的进一步的补偿事务。然而,在大多数应用中,如果不能执行诸如对al的简单写入,则系统已经遭受致命的问题并且不能继续执行。
[0076]对于性能而言关键的问题是当要求跨多个sysdb处理的数据模型时对跨多个sysdb处理的数据模型仔细分区,以及指定约束以使得当存在跨分区约束时,如果可行的话,则将它们被指定为异步的。
[0077]处理异步等式约束的应用逻辑不能假定约束严格成立。然而,该逻辑可以经常依赖于约束语义的更弱的形式。例如,如果在上面的示例中aO是缓慢改变的值,则也可以期待al接近于适当的值(即使不是完全正确)。这是因为,在对aO的任意更新之后立即正常地执行用以更新al的补偿事务。
[0078]类似地,在各组集之间的等式约束的情况下,如果确定的组集再次相对缓慢地改变,则所确定的组集可以充分地近于进行使用。例如,如果应用逻辑在所确定的组集上进行迭代以计算一些统计量,则具有近似精确的组集对于该统计计算的目的而言可能是足够的。
[0079]最终,某个应用逻辑可以仅处理第二 sysdb上的状态,并且因此无论状态的两个分区的异步更新行为如何,都不遭遇到它们之间的严格一致性的问题。
[0080]松弛断言约束
实际上,真实世界约束经常比针对顺序执行来常规地声明的那些约束更松弛。例如,在经典的订单存货系统中,可以引述被允许下订单的物品的数目不应超过存货中的数目。然而,在现实中,实际关心的是避免不必要地使得消费者失望并且招致针对退货订单的商业成本。此外,倘若有损坏、失窃以及数据捕获错误,那么可用的并且适合于装运的实际存货在数据模型中并不是准确可知的。因此,实际的计算机存储的值充其量是对于订单而言可用的物品的数目的良好估算。可以在此基础上使约束更为近似。
[0081 ] 在一个实施例中,可以通过指示一个或更多个属性可以使用它们的先前的值来将约束指定为是近似的。例如,更早些的示例的断言约束可以被指定为:
39 > b,prev + c;
指示更新C的事务可以只是使用b的快照值,而不需要针对对于属性b的并发写入进行检查。这种松弛约束消除了对于识别与该约束关联的读取-写入集合以及重新估计约束的需要。
[0082]如由’ prev前缀所指定的先前值的定义是在当前事务的开始时间的属性的值。因此,如果该属性并未与当前事务并发地更新,则其同样可以是当前值。
[0083]应用逻辑可以通过能够有效地假定断言约束近似为真来使用松弛语义。在一些情况下,可以紧密地估算这样的近似。例如,考虑银行透支的情况,假定事务在与一天相比相对短的时间段中完成,如果某个人在给定时间间隔内可以支取的量被限制在比如D美元,则在D美元内断言账户未被透支是正确的。
[0084]在针对开始时间和提交时间使用实时时钟的实施例中,应用还可以获知属性的快照值(即在开始时间取得)与当前时间之间的时间间隔。该获知的间隔还可以允许应用界定断言约束表达式的不准确度。
[0085]通过提供用以指定松弛断言约束的单元,与在不允许这些松弛语义的情况下就指定所有约束相比,本发明的基于约束的一致性可以被提供有更高的效率。这对于可能横跨数据模型分区边界的约束的情况而言特别为真,因为于是松弛语义能够避免执行分布式事务及其相关联的往返通信消息成本和延迟。
[0086]事务的基于轮次的实现
并不是每个代理单独地提交事务,替换的结构是将每个代理的事务提交绑定到由(轮次)时钟所指示的系统宽度轮次完成。轮次被跨应用同步,以使得代理直到其已经从执行其它代理的轮次i_l的其它代理接收到与其相关的所有更新才开始处理轮次i。通常,这是通过直到所有代理已经指示它们的轮次i_l的完成才允许任意代理进入轮次i来实现的。事实上,来自时钟的每个新轮次消息指示由代理进行新事务的开始,还进行动作以确保其已经接收到来自先前轮次的状态更新。代理然后完成轮次处理,并且响应于时钟来有效地提交事务。如果代理在给定轮次期间没有更新要执行,则其有效地提交空事务。这带来相对低的开销。
[0087]图5提供被组织成轮次的事务的示意性图解。在此,轮次I开始于时间tls并且结束于时间tle,轮次2开始于时间t2s并且结束于时间t2e,并且轮次3开始于时间t3s并且结束于时间t3e。期待代理a、b、c和d每个轮次执行一个事务(其可以是空事务)。事务针对在轮次I中由代理a进行的事务被标记Tla,针对在轮次3中由代理d进行的事务被标记T3d,等等。新的轮次通常直到在所有代理已经完成先前轮次(即通过提交或中止它们的相应事务)之后才开始。每个代理在轮次的开始时在逻辑上开始其事务。其实际的执行开始可能由于对约束进行调度的处理而被延迟,如图5所示。类似地,每个代理的事务在轮次的结束时在逻辑上完成(即提交)。其实际的执行可能完成得更早,因为其与在轮次时间期间可用的处理相比要做的事情更少。对于该一般方案的例外是可能的。例如,图5上的事务Tlb横跨两个轮次。因此,在相对少的事务占据多于一个的轮次的情况下,如果大多数事务在单个轮次内发生,则我们将事务当作为被组织成轮次。
[0088]在一个实施例中,可以中止单独的代理(跨越(trans))动作。在此情况下,动作被中止的代理要么立刻接收对于该效果的指示要么在下一轮次的开始时接收对于该效果的指示。这是关于如何操控代理的动作的中止的应用级别决定。例如,在一些情况下,代理在接下来的轮次中可能仅仅是重试事务,或者采取替换的动作。替换地,可以停滞当前轮次的完成,直到代理已经成功地重试同一事务。在一些情况下,这等同于并且事实上能够被实现为代理失效和重启。
[0089]在实施例中,可以通过以下来实现快照行为:一旦新的轮次已经开始,就在每个参与代理处在接收上阻断更新;一旦轮次完成,就仅释放要被提供给应用代理的那些更新。在中止的情况下,中止消息被发送到每个代理,每个代理丢弃这些被阻断并被排队的更新,确保这些代理不看到其中发生中止的轮次的结果。如果仅丢弃中止处理所生成的更新,则仅该中止处理需要针对当前轮次重试其处理。否则,所有处理复原到它们从轮次开始之时起的状态,并且针对当前轮次对处理进行重做。
[0090]替换地,可以生成更新消息作为将中止处理的状态复原到轮次的开始的部分,在该中止处理的后续重试生成提供重试处理的结果的更新消息的情况下,这有效地复原状态以撤销由该中止处理生成的改变。
[0091]作为另一替换,事务机制可以依赖于由中止和重试处理生成的新的消息,在这些消息被针对下一轮次在代理中被解除阻断并处理之前,中止和重试处理在每个接收处理的被阻断并排队的消息中提供对状态的更新以提供正确的净状态结果。例如,如果第一被中止的处理将变量“foo”设置为3,并且随后的重试将变量“foo”设置为4,则被阻断并被排队的消息包含“foo”为3的一个设置后接“foo”为4的一个设置,从而代理的状态中的净结果是正确的值(在此情况下,即4)。
[0092]可以通过使处理重启来操控在轮次期间的处理的失效,使之恢复其从轮次开始之时起的状态,并且对轮次的处理进行重做。在此情况下,除了有可能延迟轮次的完成之外,失效对于事务轮次处理是透明的。
[0093]在一些应用的情况下,可能可行的是,即使所指定的处理中的一个或更多个还未完成它们的处理并且还未对轮次时钟作出响应,也允许完成该轮次。例如,如果所指定的处理已经指示完成最后三个轮次中的一个之内的处理,则轮次机制可以继续。这样的处理可能遭遇由在中间轮次中提交其事务的另一处理进行的并发更新。例如,图5的事务Tlb将需要考虑来自事务Tla、Tlc和Tld的并发更新。
[0094]在一些应用的情况下,可以基于特定处理对于对应用正确性没有影响的状态作出的改变,而允许在轮次机制外部执行这样的处理的过程。例如,温度传感器处理可以利用连续值之间的小的差异来周期性地更新温度。应用逻辑可以被设计为即使这与基于轮次的事务并发地发生(即温度在轮次的中间显现为改变),也正确地进行操作。这可以是基于轮次的计算内的并发更新的另一源。
[0095]在实施例中,存在用以指示在沿着上面描述的优化线路的轮次内的特定代理处理的特殊操控的规定。例如,处理可以指示是在当前轮次中需要重试事务的中止还是可以跳到(slip)下一轮次。可以在登记到轮次时钟的代理处理的动作中提供该指示,以指示其正参与轮次,即,作为轮次登记处理中的参数。因此,实施例可以允许每个应用处理在操控中止和失效中选择不同的优化,目的是在仍然确保应用正确性的同时使对这些事件的应用性能的影响最小化。
[0096]在基于轮次的实现的情形下,’next后缀被用于指明在下一轮次中对值进行更新。在当前事务可能横跨多个轮次时,’ prev后缀可以指代被并发地更新的值。也就是说,该值可以在中间轮次中的一个期间已经被更新。
[0097]基于轮次的方法就用以发起的消息和提交事务这两者而言减少了事务的成本,而且还减少了指定’prev约束值的需要,或者反过来减少了未能做到这样的成本。
【权利要求】
1.一种确保与数据模型有关的并发事务的一致性的方法,所述方法包括: 提供与所述数据模型中的数据有关的约束的集合; 执行至少两个事务,其中,所述至少两个事务中的每一个具有对应的开始时间,并且依赖于从开始时间之时起所述数据模型的部分或全部对应快照; 其中,所述至少两个事务中的当前事务具有当前开始时间和当前目标提交时间,并且其中,在所述当前开始时间之后并且在所述当前目标提交时间之前的一个或更多个中间时间,所述至少两个事务的一个或更多个并发事务已经提交给所述数据模型; 执行提交处理检查,提交处理检查自动地确定是否能够与至少来自a)所述当前事务的快照和b)所述一个或更多个并发事务对所述数据模型所作的改变这两者的约束的集合一致地提交所述当前事务; 如果能够使得所述当前事务与约束的集合一致,则自动地提交所述当前事务;以及 如果不能使得所述当前事务与约束的集合一致,则自动地中止所述当前事务。
2.如权利要求1所述的方法,其中,所述提交处理检查包括: 执行写入-写入冲突解决方案。
3.如权利要求1所述的方法,其中,所述提交处理检查包括: 根据由所述当前事务执行的操作来更新所述当前事务的快照,以提供被更新的快照。
4.如权利要求1所述的方法,其中,所述提交处理检查包括: 根据由并发事务中的一个或更多个作出的所提交的改变来更新所述当前事务的快照,以提供被合并的快照。
5.如权利要求4所述的方法,其中,所述提交处理检查包括: 使用所述被合并的快照来估计约束的集合中的一个或更多个断言约束。
6.如权利要求4所述的方法,其中,所述提交处理检查包括: 执行写入-写入冲突解决方案。
7.如权利要求1所述的方法,其中,所述提交处理检查包括: 针对所述当前事务确定所述数据模型的将要由于提交所述当前事务而作为约束的集合中的更新约束的结果被更新的目标成员; 确定提交所述当前事务以及根据更新约束来更新目标成员是否与约束的集合一致。
8.如权利要求1所述的方法,其中,通过使用公共时钟来提供所述至少两个事务中的一些或全部的开始和提交,以按轮次组织事务中一些或全部。
9.如权利要求1所述的方法,其中,约束的集合包括选自包括以下项的组的一个或更多个约束:断言约束、更新约束、异步约束以及松弛断言约束。
10.如权利要求1所述的方法,其中,约束的集合充分地确保并发事务应用程序的正确行为。
11.如权利要求1所述的方法,其中,所述提交处理检查包括:执行用户供给的用于检查约束的集合的代码。
12.如权利要求1所述的方法,其中,所述提交处理检查包括:执行自动生成的用于检查约束的集合的约束检查代码。
13.如权利要求12所述的方法,其中,从约束的集合生成自动生成的约束检查代码。
【文档编号】G06F9/46GK104252382SQ201410220268
【公开日】2014年12月31日 申请日期:2014年5月23日 优先权日:2013年6月25日
【发明者】D.R.彻里顿 申请人:奥普塔姆软件股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1