发明内容
本发明要解决的技术问题是提供一种支持服务恢复属性的多样性和多种控制模式、能够保证并发调度的可串行性和可恢复性、避免饿死现象发生,允许多个执行了不可补偿事务的组合服务实例并发调度和执行、支持服务实例之间的动态冲突检测、可有效减少长期运行事务的连锁夭折的基于事务的服务状态一致性维护方法。
为了解决上述技术问题,本发明采用的技术方案为:
一种基于事务的服务状态一致性维护方法,其实施步骤如下:
1)预先构建用以区分提交了不可补偿服务的组合服务实例与其它组合服务实例的可回滚组合服务实例集合和带有等待队列的不可回滚组合服务实例集合,其中可回滚组合服务实例集合中组合服务实例的执行结果可被消除,而带有等待队列的不可回滚组合服务实例集合中的组合服务实例已执行不可补偿的服务,执行结果不能完全撤销;设定系统中组合服务实例已执行时间的阀值;组合服务实例被调度的时间先后采用时戳来标识,从待调度组合服务队列中获取被调度的组合服务实例,判断是否由于冲突原因导致所述被调度的组合服务实例曾被夭折,如果所述被调度的组合服务实例由于冲突原因曾被夭折则维持原时戳,否则按照单调递增的方式给所述被调度的组合服务实例分配一个新的时戳;将所述被调度的组合服务实例加入到可回滚组合服务实例集合中,完成被调度的组合服务实例的初始化;
2)从被调度的组合服务实例中获取一个服务实例作为当前服务实例,将当前服务实例对应的组合服务实例的已执行时间在原值的基础上增加当前服务实例的已执行时间;判断以下两个条件是否同时成立,条件①:当前服务实例对应的组合服务实例的已执行时间大于设定的已执行时间阀值,条件②:当前服务实例不是补偿服务,如果两个条件同时成立,则将当前服务实例的恢复属性设置为“不可补偿且不可重试”;判断当前服务实例的恢复属性是否为“可忽略”,当恢复属性非“可忽略”时则直接为当前服务实例分配执行凭证并执行它,否则先为当前服务实例申请获得执行凭证,然后再为当前服务实例分配执行凭证并执行它;最终判断当前服务实例的恢复属性为“可重试”或“不可补偿且不可重试”、当前服务实例与不可回滚组合服务实例集合中某个组合服务实例中的服务实例冲突两个条件是否同时成立,在所述两个条件同时成立时,将当前服务实例对应的组合服务实例移入所述不可回滚组合服务实例集合的等待队列;判断当前服务实例对应的组合服务实例是否同时存在于所述可回滚组合服务实例集合和不可回滚组合服务实例集合等待队列中,如果同时存在则将当前服务实例对应的组合服务实例移出所述不可回滚组合服务实例集合的等待队列并从可回滚组合服务实例集合中删去,然后将当前服务实例对应的组合服务实例移入所述不可回滚组合服务实例集合中;
3)判断被调度的组合服务实例的所有服务实例是否已经执行完毕,如果被调度的组合服务实例中仍有服务实例尚未执行完毕,则跳转执行步骤2);否则,如果被调度的组合服务实例中所有服务实例已经执行完毕,则提交被调度的组合服务实例。
进一步地,所述步骤2)中为当前服务实例申请获得执行凭证的详细步骤如下:
2.1)判断以下两个条件是否同时成立,条件①:当前服务实例对应的组合服务实例在不可回滚组合服务实例集合中,条件②:当前服务实例与可回滚的组合服务实例集合中某个组合服务实例的一个已获取执行凭证的服务实例是冲突的,如果上述两个条件同时成立,则对与当前服务实例冲突的服务实例对应的组合服务实例进行夭折和失效恢复;否则,跳转执行下一步;
2.2)判断以下三个条件是否同时成立,条件①:当前服务实例对应的组合服务实例在可回滚组合服务实例集合中,条件②:当前服务实例与可回滚的组合服务实例集合中某个组合服务实例的一个已获取执行凭证的服务实例冲突,条件③:当前服务实例对应的组合服务实例的时戳小于与当前服务实例冲突的服务实例对应的组合服务实例的时戳,如果上述三个条件同时成立,则对与当前服务实例冲突的服务实例对应的组合服务实例进行夭折和失效恢复;否则,跳转执行下一步;
2.3)判断以下两个条件是否同时成立,条件①:当前服务实例对应的组合服务实例在可回滚组合服务实例集合中,条件②:当前服务实例与不可回滚的组合服务实例集合中某个组合服务实例的一个已获取执行凭证的服务实例冲突,如果上述两个条件同时成立,则控制当前服务实例对应的组合服务实例进入等待状态,且在与当前服务实例冲突的服务实例对应的组合服务实例结束后返回重新执行步骤2.3);否则,跳转执行下一步;
2.4)判断以下三个条件是否同时成立,条件①:当前服务实例的恢复属性为“可重试”或“不可补偿且不可重试”,条件②:当前服务实例对应的组合服务实例与某个被调度的组合服务实例冲突,条件③:当前服务实例对应的组合服务实例的时戳大于冲突的组合服务实例的时戳,如果上述三个条件同时成立,则控制当前服务实例对应的组合服务实例进入等待状态,且在与当前服务实例对应的组合服务实例冲突的组合服务实例结束后跳转执行步骤2.3);否则,跳转执行下一步;
2.5)判断当前服务实例的恢复属性为“可重试”或“不可补偿且不可重试”、当前服务实例对应的组合服务实例在不可回滚组合服务实例集合中、当前服务实例对应的组合服务实例与不可回滚组合服务实例集合中的某个组合服务实例冲突三个条件是否同时成立,如果上述三个条件同时成立,则按照时戳大小将当前服务实例对应的组合服务实例插入不可回滚组合服务实例集合的等待队列中,当前服务实例对应的组合服务实例进入等待状态,直至当前服务实例对应的组合服务实例的时戳成为不可回滚组合服务实例集合的等待队列中最小的时戳时跳转执行步骤2.3);否则,为当前服务实例分配执行凭证,执行当前服务实例。
进一步地,所述步骤2.1)和2.2)中对与当前服务实例冲突的服务实例对应的组合服务实例进行夭折和失效恢复的详细步骤如下:
2.1.1)通过调用组合服务引擎外部的失效恢复模块,生成用于补偿并撤销其执行结果的服务或者组合服务,将所述服务或者组合服务提交到待调度组合服务队列中;
2.1.2)撤销当前服务实例对应的组合服务实例中已执行服务实例获得的执行凭证;
2.1.3)将当前服务实例对应的组合服务实例从所属的可回滚组合服务实例集合或不可回滚组合服务实例集合中移出。
进一步地,所述步骤3)中提交被调度的组合服务实例的详细步骤如下:
3.1)遍历被调度的组合服务实例中的服务实例,判断以下两个条件是否同时成立,条件①:遍历的当前服务实例是否与任意某个组合服务实例的一个获取了执行凭证的服务实例冲突,条件②:被调度的组合服务实例的时戳大于与当前服务实例发生冲突的服务实例对应的组合服务实例的时戳,如果上述两个条件同时成立,则控制被调度的组合服务实例进入等待状态,并检测与当前服务实例发生冲突的服务实例对应的组合服务实例是否已经结束,如果与当前服务实例发生冲突的服务实例对应的组合服务实例已经结束则跳转执行下一步;
3.2)撤销被调度的组合服务实例中已执行服务实例所获得的执行凭证;
3.3)将被调度的组合服务实例从所属的可回滚组合服务实例集合或不可回滚组合服务实例集合中移出。
本发明基于事务的服务状态一致性维护方法具有下述优点:
1、本发明提出的基于事务的方法能够保证并发调度的可串行性和可恢复性、避免饿死现象的发生,从而维护服务状态的一致性。首先,假设该调度中存在组合服务实例形成的一个等待环,任取环中的两个服务实例CSi和CSj,本发明预先构建可回滚组合服务实例集合(REC集)和带有等待队列的不可回滚组合服务实例集合(NREC集),这两个服务实例属于REC集或带有等待队列的NREC集,通过分别分析服务实例CSi和CSj在REC集或带有等待队列的NREC集中分布的四种组合情况可知,本发明中相关操作步骤不会引起服务实例CSi和CSj间的基于冲突的循环等待,因此调度中不存在等待环,该方法能保证调度的可串行性;第二,本发明通过动态维护REC集和带有等待队列的NREC集来保证NREC集中的组合服务实例是不可补偿的,通过将与NREC集中成员冲突的组合服务实例保留在由可恢复的组合服务组成的REC集中,可避免其由于冲突引发的不可补偿的组合服务的夭折,从而保证调度的可恢复性;第三,本发明能够保证调度的可串行性,调度中不存在死锁,即不存在循环等待情况,且一般情况下,时戳较小的实例的优先级高,时戳大的实例要么等待,要么被夭折,虽然时戳小的实例也可能等待时戳大的实例,但被等待的实例将最终完成并提交,被夭折的实例再次参与调度时,仍然维持原时戳,因此本发明在调度中也不存在饿死现象。
2、本发明能够有效减少系统资源开销。首先,本发明中NREC集中包含的都是已执行不可补偿的服务且执行结果不能完全撤销的组合服务实例,从本发明步骤2)的调度组合服务实例中的当前服务实例的步骤可以看出,NREC集中的组合服务实例数目不是唯一的,即本发明允许多个执行了不可补偿事务的组合服务实例的并发调度和执行,从而在保证可串行性和可恢复性的同时,避免了过程锁机制只允许一个组合服务实例执行不可补偿服务的限制;第二,本发明能够支持服务的恢复属性的多样性,通过引入“可忽略”(non-vital)、“可补偿”(compensable)、“可重试”(retirable)、“不可补偿且不可重试”(pivot)四种恢复属性,允许服务/组合服务实例在被夭折或产生失效时通过补偿、重试、执行可选路径等方式提交,从而可提高组合服务实例的提交率,减少单一恢复属性下频繁夭折引起的系统资源损耗;第三,本发明中执行凭证分发、以及服务实例的调度流程中均考虑到了长事务的中途夭折会造成资源的浪费,提出了组合服务实例已执行时间的阀值,一旦某组合服务实例的已执行时间超过该值,那么夭折该组合服务实例将被认为是不可接受的,具体做法是将该组合服务实例的当前被调度服务实例的恢复属性设为“不可补偿且不可重试”(pivot),即不可补偿且不可重试的,这样一旦该服务实例获得执行凭证被调度执行,其所在组合服务实例最终进入NREC集,从而避免将其加入到连锁夭折中,造成不必要的损失,与基于混合粒度冲突检测的调度方法相比,能够有效减少连锁夭折的发生。
3、本发明支持服务实例之间的动态冲突检测且支持多种控制模式,具有良好的灵活性与适应性。首先,从本发明的冲突检测办法可知,本发明支持冲突的动态检测,通过构建的冲突矩阵以及矩阵中基于服务操作语义和持久存储访问特性的冲突检测函数来动态判断服务实例或者组合服务实例之间是否存在冲突,从而为正确调度做出辅助决策,与基于QoS的并发调度中在调度前获取所有冲突信息的静态冲方法相比,具有更好的灵活性;第二,本发明通过将并发调度模块与控制模式解释模块相结合,不仅可以用于平坦、嵌套结构的组合服务的调度,还支持以串行、并行、互斥、优先、循环等多种控制模式连接的复杂组合服务的调度,可用于组成服务之间具有复杂偏序和依赖关系的组合服务的并发调度,适用范围更广。
综上所述,本发明基于事务的服务状态一致性维护方法支持服务恢复属性的多样性和多种控制模式、能够保证并发调度的可串行性和可恢复性、避免饿死现象发生,允许多个执行了不可补偿事务的组合服务实例并发调度和执行、支持服务实例之间的动态冲突检测、可有效减少长期运行事务。
具体实施方式
如图2和图3所示,本实施例基于事务的服务状态一致性维护方法的实施步骤如下:
1)预先构建用以区分提交了不可补偿服务的组合服务实例与其它组合服务实例的可回滚组合服务实例集合(以下简称REC集)和带有等待队列的不可回滚组合服务实例集合(以下简称NREC集),其中REC集中组合服务实例的执行结果可被消除,而带有等待队列的NREC集中的组合服务实例已执行不可补偿的服务,执行结果不能完全撤销;设定系统中组合服务实例已执行时间的阀值Tref;组合服务实例被调度的时间先后采用时戳来标识,从待调度组合服务队列中获取被调度的组合服务实例CSi,判断是否由于冲突原因导致被调度的组合服务实例CSi曾被夭折,如果被调度的组合服务实例CSi由于冲突原因曾被夭折则维持原时戳,否则按照单调递增的方式给被调度的组合服务实例分配一个新的时戳TS(CSi);将被调度的组合服务实例CSi加入到REC集中,完成被调度的组合服务实例CSi的初始化。
2)通过调用组合服务引擎的控制模式解释模块,从被调度的中获取一个服务实例作为当前服务实例Sij,将当前服务实例Sij对应的组合服务实例CSi的已执行时间在原值的基础上增加当前服务实例的已执行时间(CSi的已执行时间:= CSi的已执行时间+ Sij的执行时间);判断以下两个条件是否同时成立,条件①:当前服务实例Sij对应的组合服务实例CSi的已执行时间大于设定的已执行时间阀值Tref,条件②:当前服务实例Sij不是补偿服务,如果两个条件同时成立,则将当前服务实例Sij的恢复属性设置为“不可补偿且不可重试”(pivot);判断当前服务实例Sij的恢复属性是否为“可忽略”(non-vital),当恢复属性非“可忽略”(non-vital)时直接为当前服务实例Sij分配执行凭证并执行它,否则先为当前服务实例Sij申请获得执行凭证,然后再为当前服务实例Sij分配执行凭证并执行它;最终判断当前服务实例Sij的恢复属性为“可重试”(retriable)或“不可补偿且不可重试”(pivot)、当前服务实例Sij与NREC集中某个组合服务实例中的服务实例冲突两个条件是否同时成立,在两个条件同时成立时,将当前服务实例Sij对应的组合服务实例CSi移入NREC集的等待队列;判断当前服务实例Sij对应的组合服务实例CSi是否同时存在于REC集(CSi∈REC)和NREC集的等待队列中,如果同时存在则将当前服务实例Sij对应的组合服务实例CSi移出NREC集的等待队列并从REC集中删去,然后将当前服务实例Sij对应的组合服务实例CSi移入NREC集中;
3)判断被调度的组合服务实例CSi的所有服务实例是否已经执行完毕,如果被调度的组合服务实例CSi中仍有服务实例尚未执行完毕,则跳转执行步骤2);否则,如果被调度的组合服务实例CSi中所有服务实例已经执行完毕,则提交被调度的组合服务实例CSi。
参见图3,其中从上往下第一条水平虚线上侧的流程即为被调度的组合服务实例CSi的初始化流程,从上往下第二条水平虚线下侧的流程即为被调度的组合服务实例CSi的提交流程。被调度的组合服务实例CSi由多个服务实例通过串行、并行、互斥、优先等关系连接而组成,两条水平虚线之间的流程即为针对被调度的组合服务实例CSi中的每一个当前服务实例Sij的执行流程(包括申请执行凭证,在获得凭证,即被分配凭证后后执行该服务实例等)。每一个当前服务实例Sij申请执行凭证前都需要所在组合服务实例在步骤1)被初始化过,只有在当前服务实例Sij对应的被调度的组合服务实例CSi中所有需要执行完的服务实例被分配了执行凭证且得到执行后,才能够提交被调度的组合服务实例CSi。并不是每一个当前服务实例Sij执行完毕后即可提交被调度的组合服务实例CSi,步骤2)的流程完成只是步骤3)提交的必要条件,而不是充分条件。
参见图3,本实施例中步骤2)中为当前服务实例申请获得执行凭证的详细步骤如下:
2.1)判断以下两个条件是否同时成立,条件①:当前服务实例Sij对应的组合服务实例CSi在NREC集中(即CSi∈NREC),条件②:当前服务实例Sij与可回滚的组合服务实例集合REC中某个组合服务实例CSk的一个已获取执行凭证的服务实例Skl是冲突的,如果上述两个条件同时成立,则对与当前服务实例Sij冲突的服务实例Skl对应的组合服务实例CSk进行夭折和失效恢复;否则,跳转执行下一步;
2.2)判断以下三个条件是否同时成立,条件①:当前服务实例Sij对应的组合服务实例CSi在REC集中(即CSi∈REC),条件②:当前服务实例Sij与可回滚的组合服务实例集合REC中某个组合服务实例CSk的一个已获取执行凭证的服务实例Skl冲突、条件③:当前服务实例Sij对应的组合服务实例CSi的时戳TS(CSi)小于与当前服务实例Sij冲突的服务实例Skl对应的组合服务实例CSk的时戳[即TS(CSi)<TS(CSk)],如果上述三个条件同时成立,则对与当前服务实例Sij冲突的服务实例Skl对应的组合服务实例CSk进行夭折和失效恢复;否则,跳转执行下一步;
2.3)判断以下两个条件是否同时成立,条件①:当前服务实例Sij对应的组合服务实例CSi在REC集中(即CSi∈REC),条件②:当前服务实例Sij与不可回滚的组合服务实例集合NREC中某个组合服务实例CSk的一个已获取执行凭证的服务实例Skl冲突,如果上述两个条件同时成立,则控制当前服务实例Sij对应的组合服务实例CSi进入等待状态,且在与当前服务实例Sij冲突的服务实例Skl对应的组合服务实例CSk结束后返回重新执行步骤2.3);否则,跳转执行下一步;
2.4)判断以下三个条件是否同时成立,条件①:当前服务实例Sij的恢复属性为“可重试”(retriable)或“不可补偿且不可重试”(pivot),条件②:当前服务实例Sij对应的组合服务实例CSi与某个被调度的组合服务实例CSk冲突,条件③:当前服务实例Sij对应的组合服务实例CSi的时戳大于冲突的组合服务实例CSk的时戳[TS(CSi) > TS(CSk)],如果上述三个条件同时成立,则控制当前服务实例Sij对应的组合服务实例CSi进入等待状态,且在与当前服务实例Sij对应的组合服务实例CSi冲突的组合服务实例CSk结束后跳转执行步骤2.3);否则,跳转执行下一步;
2.5)判断当前服务实例的恢复属性为“可重试”(retriable)或“不可补偿且不可重试”(pivot)、当前服务实例Sij对应的组合服务实例CSi在NREC集中、当前服务实例Sij对应的组合服务实例CSi与NREC集中的某个组合服务实例CSk冲突三个条件是否同时成立,如果上述三个条件同时成立,则按照时戳大小将当前服务实例Sij对应的组合服务实例CSi插入NREC集的等待队列中,当前服务实例Sij对应的组合服务实例CSi进入等待状态,直至当前服务实例Sij对应的组合服务实例CSi的时戳成为NREC集的等待队列中最小的时戳时,跳转执行步骤2.3);否则,为当前服务实例分配执行凭证,执行当前服务实例。
本实施例中,已经执行并提交了不可补偿服务的组合服务实例是不允许被夭折的。如图4所示,为了区分这种服务实例与被调度的其它服务实例,将被调度的组合服务实例动态地分为两个集合:REC集(执行结果可被消除)和NREC集(已执行不可补偿的服务,执行结果不能完全撤销)。其中,REC由正在运行的可以被补偿的组合服务实例组成,而NREC是由已经执行并提交了不可补偿服务的、相互之间不会产生冲突的组合服务实例组成。初始化时,所有的组合服务实例都属于REC;系统维持一个NREC的等待队列,等待队列中的元素是将要执行不可补偿服务、但与NREC中某组合服务实例相互冲突的实例(例如图中CS8和CS9),一旦冲突解除,则允许等待队列中的实例加入NREC。当一个组合服务实例执行了不可补偿的服务并且不会与NREC中已有任何组合服务实例产生冲突时,该组合服务实例被移至NREC中。图4中,虚线箭头表示组合服务实例之间由于冲突而引起的等待关系,例如CS3和CS4之间、CS8和CS2之间、CS9和CS5之间,实线箭头表示等待进入NREC或其等待队列。长事务的中途夭折会造成资源的浪费、时间的损失,对系统性能的影响很大;同样,在产生连锁夭折时,执行时间长的组合服务实例的夭折会降低系统运行效率。为此,需设定已执行时间阀值,一旦某组合服务实例的已执行时间超过该值,那么夭折该组合服务实例将被认为是不可接受的,具体做法是当已执行时间超过设定的已执行时间阀值时,将该组合服务实例的当前被调度服务实例的恢复属性设为“不可补偿且不可重试”(pivot),即不可补偿且不可重试的,这样一旦该服务实例获得执行凭证被调度执行,其所在组合服务实例最终进入NREC(即图4中属于NREC的超过已执行时间阀值的实例),从而避免将其加入到连锁夭折中,造成不必要的损失。
如图5所示,本实施例步骤2.1)和2.2)中对与当前服务实例冲突的服务实例对应的组合服务实例进行夭折和失效恢复的详细步骤如下:
2.1.1)通过调用组合服务引擎外部的失效恢复模块,生成用于补偿并撤销其执行结果的服务或者组合服务,将服务或者组合服务提交到待调度组合服务队列中;
2.1.2)撤销当前服务实例Sij对应的组合服务实例CSi中已执行服务实例获得的执行凭证;
2.1.3)将当前服务实例Sij对应的组合服务实例CSi从所属的REC集或NREC集中移出。
如图6所示,本实施例步骤2)中提交被调度的组合服务实例CSi的详细步骤如下:
3.1)遍历被调度的组合服务实例CSi中的服务实例,判断以下两个条件是否同时成立,条件①:遍历的当前服务实例Sij是否与任意某个组合服务实例CSk的一个获取了执行凭证的服务实例Skl冲突,条件②:被调度的组合服务实例CSi的时戳大于与当前服务实例Sij发生冲突的服务实例Skl对应的组合服务实例CSk的时戳(即TS(CSi)> TS(CSk)),如果上述两个条件同时成立,则控制被调度的组合服务实例CSi进入等待状态,并检测与当前服务实例Sij发生冲突的服务实例Skl对应的组合服务实例CSk是否已经结束,如果与当前服务实例Sij发生冲突的服务实例Skl对应的组合服务实例CSk已经结束则跳转执行下一步;
3.2)撤销被调度的组合服务实例CSi中已执行服务实例所获得的执行凭证;
3.3)将被调度的组合服务实例CSi从所属的REC集或NREC集中移出。
如图7所示,本实施例中具体是通过扩展组合服务引擎、构造新的并发调度模块并替换基于已有方法的并发调度模块实现的。本实施例在保留组合服务引擎中的控制模式解释模块和执行代码激活模块的基础上构造新的并发调度模块,然后在并发调度模块内部构造并添加初始化子模块、动态冲突检测子模块、执行凭证分发子模块、夭折与失效恢复子模块、组合服务提交子模块、集合维护子模块共六个子模块,最后用新构造的并发调度模块替换现有的并发调度模块(先移除基于现有方法的并发调度模块,然后添加新构造的并发调度模块,接着建立新添加的并发调度模块与系统中原有模块间的接口)。然后,通过初始化子模块、动态冲突检测子模块、执行凭证分发子模块、夭折与失效恢复子模块、组合服务提交子模块、集合维护子模块共六个子模块完成本实施例前述的实施步骤。首先采用初始化子模块进行被调度的组合服务实例的初始化,包括从待调度组合服务队列中获取被调度的组合服务实例、根据该实例是否由于冲突原因曾被夭折进行区别处理、将实例加入到REC集中、逐个获取已被初始化的组合服务实例的服务实例,并激活服务实例调度;然后由执行凭证分发子模块调度组合服务实例的某服务实例,包括计算该服务实例所在组合服务实例的已执行时间,根据已执行时间是否大于阀值来决定是否设置该服务实例的恢复属性为“不可补偿且不可重试”(pivot),申请获得执行凭证(根据恢复属性、已执行时间、冲突情况、时戳大小确定组合实例是否需要被夭折或进入等待状态),为服务实例分配执行凭证并执行该服务实例,如果该服务实例的恢复属性为“可重试”(retriable)或“不可补偿且不可重试”(pivot),则根据具体情况维护REC集和NREC集;由夭折与失效恢复子模块负责夭折组合服务实例并进行失效恢复,包括调用失效恢复模块,生成用于补偿并撤销其执行结果的服务/组合服务,将该服务/组合服务提交到待调度组合服务队列中,撤销组合服务实例中已执行服务实例获得的执行凭证,将组合服务实例从REC集或NREC集中移出;当组合服务实例完成给定任务,发出提交请求时,并发调度模块的组合服务提交子模块被激活,完成该组合服务实例提交,包括根据冲突情况和时间戳大小判断是否需要等待、撤销已执行服务实例所获得的执行凭证、将该组合服务实例从REC集或NREC集中移出,因此能够采用扩展的组合服务引擎进行基于事务冲突检测的并发调度,确保服务调度的可串行性和可恢复性,将系统的服务从一个一致性状态转换到另一个一致性状态。
本实施例中,并发调度模块内部构造并添加初始化子模块、动态冲突检测子模块、执行凭证分发子模块、夭折与失效恢复子模块、组合服务提交子模块、集合维护子模块共六个子模块分别负责初始化组合服务、动态检测组合服务实例或服务实例之间的并发冲突、分发服务实例的执行凭证、夭折组合服务实例并进行失效恢复、完成组合服务实例的提交、维护REC集和NREC集中的组成元素。
建立新添加的并发调度模块与系统中原有模块间接口的方法为:初始化子模块调用组合服务引擎的控制模式解释模块,逐个获取已被初始化的组合服务实例的服务实例;夭折与失效恢复子模块调用失效恢复模块,将产生失效的服务的补偿服务提交给并发调度模块参与调度;夭折与失效恢复子模块、组合服务提交子模块与组合服务引擎的执行代码激活模块进行交互,根据执行代码激活模块反馈的外部程序的执行情况,夭折或者提交相应的服务实例。本实施例中,前述的六个子模块的构造和添加方法如下:
(1) 初始化子模块。初始化子模块负责初始化组合服务,包括分配时戳、将被初始化的当前组合服务实例加入正在运行且可被补偿的组合服务实例集合REC集中,按照控制模式中的偏序分别调度该组合服务实例中的各个服务。组合服务实例被调度的时间先后采用时戳来标识,每个组合服务实例CSi都被赋予一个单调递增的时戳TS(CSi)。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:若当前组合服务实例尚未被夭折过,则获取系统时间,生成时间戳,将时间戳分配给当前组合服务实例;调用集合维护子模块,将当前组合服务实例加入到REC集中;调用控制模式解释模块,逐个获取已被初始化的组合服务实例的服务实例,调用执行凭证分发子模块,对服务实例进行调度。
本实施例中,初始化子模块执行被调度的组合服务实例的初始化的步骤参见图2,并发调度模块的初始化子模块从待调度组合服务队列中获取被调度的组合服务实例CSi;接着判断CSi是否由于冲突原因曾被夭折,若是,则维持原时戳,否则分配一个新的时戳TS(CSi);然后将CSi加入到REC集中;最后调用控制模式解释模块,逐个获取已被初始化的组合服务实例的服务实例,调用执行凭证分发子模块,对服务实例进行调度。
(2) 动态冲突检测子模块。动态冲突检测子模块负责在调度过程中动态检测服务实例之间是否存在冲突。为实现冲突检测,构建服务的冲突矩阵CONF,该矩阵为n×n维(n是系统中服务的个数)的,对于任意服务Si和Sj,CONF(i, j)中存放的是一个基于该服务操作语义和持久存储访问特性的冲突检测函数confDetector(i, j),用于判断服务Si和Sj在某些特定参数下的两个实例之间是否存在冲突。如果该函数返回TRUE,则表示存在冲突,否则返回FALSE,表示不存在冲突。以存款和取款两种服务为例,deposit(amount)与withdraw(amount)的冲突检测函数通过判断两者访问的账户是否相同来确定两者是否冲突。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:该子模块被执行凭证分发子模块调用,根据CONF矩阵及对应confDetector函数来判断被调度服务实例或组合服务实例与另一个正在被调度的服务实例或组合服务实例之间是否存在冲突,从而决定是否夭折对应组合服务实例或者使其进入等待状态;该子模块也被组合服务提交子模块所调用,根据CONF矩阵及对应confDetector函数来判断被调度服务实例是否与另一个已经获得执行凭证的服务实例冲突,从而决定是否需要使该服务实例所属的组合服务实例进入等待状态。
(3) 执行凭证分发子模块。每当激活执行一个服务实例前,首先要获取它的执行凭证,根据被调度服务实例的执行是否会破坏调度的可恢复性和可串行性,确定是立即激活、延迟激活、还是夭折该服务实例或者相关服务实例的执行,具体的调度策略主要由服务的恢复属性、组合服务实例已执行时间、服务实例之间的动态冲突检测结果、组合服务实例的时戳大小四个因素决定。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:该子模块被初始化子模块调用,用于按照一定策略为已初始化的某个组合服务实例的一个服务实例分配执行凭证;该子模块调用动态冲突检测子模块来判断服务实例/组合服务实例之间是否存在冲突,并结合服务的恢复属性、组合服务实例已执行时间、组合服务实例的时戳大小等信息来确定调用夭折与失效恢复子模块对相应组合实例进行处理、还是使其进入等待状态;为服务实例分配执行凭证,调用组合服务引擎的执行代码激活模块以执行被调度服务实例;调用集合维护子模块以变更REC集和NREC集成员。
本实施例中,并发调度模块的执行凭证分发子模块调度组合服务实例CSi的服务实例Sij的具体步骤具体参见图3,其详细步骤为:首先,计算CSi的已执行时间;然后判断CSi的已执行时间是否大于阀值且Sij是否是补偿服务,若是,则将Sij的恢复属性设置为“不可补偿且不可重试”(pivot);接着,判断Sij的恢复属性是否为“可忽略”(non-vital),若是,则跳过下一步,即步骤“服务实例Sij申请获得执行凭证”;服务实例Sij申请获得执行凭证;为Sij分配执行凭证,调用组合服务引擎的执行代码激活模块以执行Sij;当Sij的恢复属性为“可重试”(retriable)或“不可补偿且不可重试”(pivot)时,判断是否与NREC集中的某个组合服务实例中的服务实例冲突,如果是,将CSi移入NREC集的等待队列,否则,当CSi REC集且在NREC集等待队列中时,将CSi移出NREC集的等待队列,并从REC集中删去,移入NREC集中。其中,服务实例Sij申请获得执行凭证具体分为以下两个步骤a)和b)进行处理。
a) 如果存在下述情况,则夭折相应的组合服务实例CSk:如果CSi NREC集,且服务实例Sij与REC集中某个CSk的一个获取了执行凭证的服务实例Skl冲突,那么调用夭折与失效恢复子模块对CSk进行处理;如果CSi∈REC集,且Sij与REC集中某个CSk的一个获取了执行凭证的服务实例Skl冲突,这时:若TS(CSi)<TS(CSk),则调用夭折与失效恢复子模块对CSk进行处理。
b) 如果存在下述情况,组合服务实例CSi进入等待状态,直至引起它等待的组合服务实例结束:如果CSi∈REC集,Sij与NREC集中某个CSk的一个获取了执行凭证的服务实例Skl冲突,那么CSi进入等待状态,直至CSk结束,然后转至第(b)步;如果Sij的恢复属性为retriable或pivot,CSi与某个被调度的组合服务实例CSk冲突,且TS(CSi) > TS(CSk),那么CSi进入等待状态,直至CSk结束,然后转至第(b)步;如果Sij的恢复属性为“可重试”(retriable)或“不可补偿且不可重试”(pivot),CSi∈NREC集,且CSi将来会与NREC集中其它某个CSk冲突,那么按照时戳大小将CSi插入NREC集的等待队列,CSi进入等待状态,直至CSi成为队列中时戳最小的实例,然后转至第(b)步。
(4) 夭折与失效恢复子模块。存在冲突的情况下,已执行不可补偿服务的组合服务实例的调度优先级相对更高,即调度中NREC集中的实例一般优先于REC集中的实例执行;在此基础上,当要调度不可补偿的服务实例时,时戳较大的组合服务实例要等待时戳较小的组合服务实例执行完毕。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:该子模块被执行凭证分发子模块所调用,在必要时用以夭折REC集中与当前被调度的组合服务实例相互冲突的组合服务实例;该子模块调用失效恢复模块,将产生失效的服务的补偿服务提交给并发调度模块参与调度;调用集合维护子模块,将当前组合服务实例从REC集或NREC集中移出。
本实施例中,夭折与失效恢复子模块的工作流程参见图5,当夭折与失效恢复子模块接收到夭折某个组合服务实例的请求时,首先调用失效恢复模块,生成用于补偿并撤销其执行结果的服务/组合服务,并将该服务/组合服务提交到待调度组合服务队列中;然后撤销组合服务CSi中已执行服务实例获得的执行凭证;最后将CSi从REC集或NREC集中移出。
(5) 组合服务提交子模块。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:当组合服务所封装的操作集合完成后,将激活组合服务提交子模块运行;该子模块调用动态冲突检测子模块来判断服务实例之间是否存在冲突,如果将要提交的组合服务实例中的某服务实例Sij与某个CSk的一个获取了执行凭证的服务实例Skl相互冲突,且TS(CSi)> TS(CSk),那么CSi进入等待状态,直至CSk结束;组合服务提交子模块还将删除已执行服务实例的执行凭证,并调用集合维护子模块将当前组合服务实例从REC集或NREC集中移出。
本实施例中,组合服务提交子模块的的工作流程参见图6,当组合服务实例CSi完成给定任务,发出提交请求时,并发调度模块的组合服务提交子模块被激活,完成CSi的提交。具体步骤为:如果Sij与某个CSk的一个获取了执行凭证的服务实例Skl冲突,且TS(CSi)> TS(CSk),那么CSi进入等待状态,直至CSk结束;撤销已执行服务实例所获得的执行凭证;将CSi从REC集或NREC集中移出。
(6) 集合维护子模块。集合维护子模块负责维护REC集和NREC集中的组成元素。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:组合服务所在系统被启动时,集合维护子模块将创建全局的REC集实例表和NREC集实例表,以及一个NREC集的等待队列;该子模块被初始化、执行凭证分发、夭折与失效恢复和组合服务提交子模块所调用,用于变更REC集和NREC集成员。
本实施例方法模块化好、步骤清晰、可操作性强。本发明所提出的方法共两个步骤,第一步扩展组合服务引擎,构造新的并发调度模块,替换基于已有方法的并发调度模块。新的并发调度模块由初始化、动态冲突检测、执行凭证分发、夭折与失效恢复、组合服务提交、集合维护六个子模块组成,各个子模块的实现流程、与其它子模块之间的接口、以及新添加的并发调度模块与系统中原有模块间的接口具体、明确;第二步采用第一步扩展而来的组合服务引擎进行基于事务冲突检测的并发调度,从初始化、组合服务及服务实例的调度、组合服务的夭折与失效恢复、组合服务的提交四个方面,确保调度的可串行性和可恢复性,将系统从一个一致性状态转换到另一个一致性状态。
如图8所示,本实施例中扩展组合服务引擎以及组合服务引擎的工作步骤如下:
第一步,扩展组合服务引擎,构造新的并发调度模块,替换基于已有方法的并发调度模块。方法是:保留组合服务引擎中的控制模式解释模块和执行代码激活模块,构造并发调度模块,并在并发调度模块内部构造并添加初始化、动态冲突检测、执行凭证分发、夭折与失效恢复、组合服务提交、集合维护六个子模块,用新构造的并发调度模块替换基于已有方法的并发调度模块。具体方法如下:
S1.1、构造并添加初始化子模块。初始化子模块负责初始化组合服务,包括分配时戳、将被初始化的当前组合服务实例加入正在运行且可被补偿的组合服务实例集合REC集(可回滚的组合服务实例集合REC集,参见第1.6步)中,按照控制模式中的偏序分别调度该组合服务实例中的各个服务。组合服务实例被调度的时间先后采用时戳来标识,每个组合服务实例CSi都被赋予一个单调递增的时戳TS(CSi)。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:若当前组合服务实例尚未被夭折过,则获取系统时间,生成时间戳,将时间戳分配给当前组合服务实例;调用集合维护子模块,将当前组合服务实例加入到REC集中;调用控制模式解释模块,逐个获取已被初始化的组合服务实例的服务实例,调用执行凭证分发子模块,对服务实例进行调度。
S1.2、构造并添加动态冲突检测子模块。并发冲突是引起数据状态不一致的根本原因,如果不存在冲突,那么任何调度都是可以接受的。因此,服务或组合服务实例之间的冲突检测在调度中是不可或缺的。动态冲突检测子模块负责在调度过程中动态检测服务实例之间是否存在冲突。为实现冲突检测,构建服务的冲突矩阵CONF,该矩阵为n×n维(n是系统中服务的个数)的,对于任意服务Si和Sj,CONF(i, j)中存放的是一个基于该服务操作语义和持久存储访问特性的冲突检测函数confDetector(i, j),用于判断服务Si和Sj在某些特定参数下的两个实例之间是否存在冲突。如果该函数返回TRUE,则表示存在冲突,否则返回FALSE,表示不存在冲突。如果服务Si和Sj的所有实例都冲突,那么CONF(i, j)=TRUE,如果两者的所有实例都不冲突,那么CONF(i, j)=FALSE,两个服务的任意实例都是可交换的。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:该子模块被执行凭证分发子模块调用,根据CONF矩阵及对应confDetector函数来判断被调度服务实例或组合服务实例与另一个正在被调度的服务实例或组合服务实例之间是否存在冲突,从而决定是否夭折对应组合服务实例或者使其进入等待状态;该子模块也被组合服务提交子模块所调用,根据CONF矩阵及对应confDetector函数来判断被调度服务实例是否与另一个已经获得执行凭证的服务实例冲突,从而决定是否需要使该服务实例所属的组合服务实例进入等待状态。
S1.3、构造并添加执行凭证分发子模块。每当激活执行一个服务实例前,首先要获取它的执行凭证,根据被调度服务实例的执行是否会破坏调度的可恢复性和可串行性,确定是立即激活、延迟激活、还是夭折该服务实例或者相关服务实例的执行,具体的调度策略主要由服务的恢复属性、组合服务实例已执行时间、服务实例之间的动态冲突检测结果、组合服务实例的时戳大小四个因素决定。恢复属性包括“可忽略”(non-vital)、“可补偿”(compensable)、“可重试”(retirable)、“不可补偿且不可重试”(pivot)四种,其中:“可忽略”是指一个服务执行不会影响数据状态,只读操作构成的服务是一种典型的可忽略的服务;如果一个服务执行结果可以通过补偿操作被撤销,则称该服务是“可补偿”的,补偿操作集合称作其补偿服务;如果一个服务经过有限次重复尝试,最终可确保提交,则称该服务是“可重试”的。已执行时间是指某组合服务实例从开始调度到当前时刻的总运行时间,初始值为0。长事务的中途夭折会造成资源的浪费、时间的损失,对系统性能的影响很大;同样,在产生连锁夭折时,执行时间长的组合服务实例的夭折会降低系统运行效率。为此,需设定已执行时间的阀值Tref,一旦某组合服务实例的已执行时间超过Tref,那么夭折该组合服务实例将被认为是不可接受的,具体做法是当某组合服务实例的已执行时间超过Tref时,将该组合服务实例的当前被调度服务实例的恢复属性设为“不可补偿且不可重试”(pivot),即不可补偿且不可重试的,这样一旦该服务实例获得执行凭证被调度执行,其所在组合服务实例最终进入NREC集,从而避免将其加入到连锁夭折中,造成不必要的损失。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:该子模块被初始化子模块调用,用于按照一定策略为已初始化的某个组合服务实例的一个服务实例分配执行凭证;该子模块调用动态冲突检测子模块来判断服务实例/组合服务实例之间是否存在冲突,并结合服务的恢复属性、组合服务实例已执行时间、组合服务实例的时戳大小等信息来确定调用夭折与失效恢复子模块对相应组合实例进行处理、还是使其进入等待状态;为服务实例分配执行凭证,调用组合服务引擎的执行代码激活模块以执行被调度服务实例;调用集合维护子模块以变更REC集和NREC集成员。
S1.4、构造并添加夭折与失效恢复子模块。存在冲突的情况下,已执行不可补偿服务的组合服务实例的调度优先级相对更高,即调度中NREC集中的实例一般优先于REC集中的实例执行;在此基础上,当要调度不可补偿的服务实例时,时戳较大的组合服务实例要等待时戳较小的组合服务实例执行完毕。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:该子模块被执行凭证分发子模块所调用,在必要时用以夭折REC集中与当前被调度的组合服务实例相互冲突的组合服务实例;该子模块调用失效恢复模块,将产生失效的服务的补偿服务提交给并发调度模块参与调度;调用集合维护子模块,将当前组合服务实例从REC集或NREC集中移出。
S1.5、构造并添加组合服务提交子模块。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:当组合服务所封装的操作集合完成后,将激活组合服务提交子模块运行;该子模块调用动态冲突检测子模块来判断服务实例之间是否存在冲突,如果将要提交的组合服务实例中的某服务实例Sij与某个CSk的一个获取了执行凭证的服务实例Skl相互冲突,且TS(CSi)> TS(CSk),那么CSi进入等待状态,直至CSk结束;组合服务提交子模块还将删除已执行服务实例的执行凭证,并调用集合维护子模块将当前组合服务实例从REC集或NREC集中移出。
S1.6、构造并添加集合维护子模块。已经执行并提交了不可补偿服务的组合服务实例是不允许被夭折的,为了区分这种实例与被调度的其它实例,将被调度的组合服务实例动态地分为两个集合:可回滚的组合服务实例集合REC集(执行结果可被消除)和不可回滚的组合服务实例集合NREC集(已执行不可补偿的服务,执行结果不能完全撤销)。其中,REC集由正在运行的可以被补偿的组合服务实例组成,而NREC集是由已经执行并提交了不可补偿服务的、相互之间不会产生冲突的组合服务实例组成。初始化时,所有的组合服务实例都属于REC集;系统维持一个NREC集的等待队列,队列中的元素是将要执行不可补偿服务、但与NREC集中某组合服务实例相互冲突的实例,一旦冲突解除,则允许等待队列中的实例加入NREC集。当一个组合服务实例CSi执行了不可补偿的服务并且不会与NREC集中已有任何组合服务实例产生冲突时,CSi被移至NREC集中。集合维护子模块负责维护REC集和NREC集中的组成元素。根据下述实现流程及与其它子模块之间的接口来构造并添加该子模块:组合服务所在系统被启动时,集合维护子模块将创建全局的REC集实例表和NREC集实例表,以及一个NREC集的等待队列;该子模块被初始化、执行凭证分发、夭折与失效恢复和组合服务提交子模块所调用,用于变更REC集和NREC集成员。
S1.7、用新构造的并发调度模块替换基于已有方法的并发调度模块。方法是:
S1.7.1、移除基于已有方法的并发调度模块;
S1.7.2、添加新构造的并发调度模块,该模块由初始化、动态冲突检测、执行凭证分发、夭折与失效恢复、组合服务提交、集合维护六个子模块组成;
S1.7.3、建立新添加的并发调度模块与系统中原有模块间的接口。具体为:初始化子模块调用组合服务引擎的控制模式解释模块,逐个获取已被初始化的组合服务实例的服务实例;夭折与失效恢复子模块调用失效恢复模块,将产生失效的服务的补偿服务提交给并发调度模块参与调度;夭折与失效恢复子模块、组合服务提交子模块与组合服务引擎的执行代码激活模块进行交互,根据执行代码激活模块反馈的外部程序的执行情况,夭折或者提交相应的服务实例。
第二步,采用第一步扩展而来的组合服务引擎进行基于动态冲突检测的事务并发调度,确保调度的可串行性和可恢复性,将系统从一个一致性状态转换到另一个一致性状态。具体方法为:
S2.1并发调度模块的初始化子模块负责被调度的组合服务实例的初始化。步骤为:
S2.1.1并发调度模块的初始化子模块从待调度组合服务队列中获取被调度的组合服务实例CSi;
S2.1.2如果CSi由于冲突原因曾被夭折,则维持原时戳,否则分配一个新的时戳TS(CSi);
S2.1.3将CSi加入到REC集中;
S2.1.4调用控制模式解释模块,逐个获取已被初始化的组合服务实例的服务实例,调用执行凭证分发子模块,对服务实例进行调度。
S2.2并发调度模块的执行凭证分发子模块负责调度组合服务实例中的某个服务实例。调度组合服务实例CSi的服务实例Sij的步骤为:
S2.2.1 CSi的已执行时间:= CSi的已执行时间+ Sij的执行时间;
S2.2.2如果CSi的已执行时间大于Tref且Sij不是补偿服务,那么将Sij的恢复属性设置为“不可补偿且不可重试”(pivot);
S2.2.3如果Sij的恢复属性为“可忽略”(non-vital),则转到第S2.2.5步;
S2.2.4服务实例Sij申请获得执行凭证:
S2.2.4.1如果存在下述情况,则夭折相应组合服务实例:
1)如果CSi∈NREC集,且Sij与REC集中某个CSk的一个获取了执行凭证的服务实例Skl冲突,那么通过调用夭折与失效恢复子模块,转至第S2.3步对CSk进行处理;
2)如果CSi∈REC集,且Sij与REC集中某个CSk的一个获取了执行凭证的服务实例Skl冲突,这时:若TS(CSi)<TS(CSk),则通过调用夭折与失效恢复子模块,转至第S2.3步对CSk进行处理。
S2.2.4.2 如果存在下述情况,CSi进入等待状态,直至引起它等待的组合服务实例结束:
1)如果CSi∈REC集,Sij与NREC集中某个CSk的一个获取了执行凭证的服务实例Skl冲突,那么CSi进入等待状态,直至CSk结束,然后转至第S2.2.4.2步;
2)如果Sij的恢复属性为“可重试”(retriable)或“不可补偿且不可重试”(pivot),CSi与某个被调度的组合服务实例CSk冲突,且TS(CSi) > TS(CSk),那么CSi进入等待状态,直至CSk结束,然后转至第S2.2.4.2步;
3)如果Sij的恢复属性为“可重试”(retriable)或“不可补偿且不可重试”(pivot),CSi∈NREC集,且CSi将来会与NREC集中其它某个CSk冲突,那么按照时戳大小将CSi插入NREC集的等待队列,CSi进入等待状态,直至CSi成为队列中时戳最小的实例,然后转至第S2.2.4.2步;
S2.2.5为Sij分配执行凭证,调用组合服务引擎的执行代码激活模块以执行Sij;
S2.2.6如果Sij的恢复属性为“可重试”(retriable)或“不可补偿且不可重试”(pivot),判断是否与NREC集中的某个组合服务实例中的服务实例冲突:如果是,将CSi移入NREC集的等待队列,否则,当CSi∈REC集且在NREC集等待队列中时,将CSi移出NREC集的等待队列,并从REC集中删去,移入NREC集中。
S2.3并发调度模块的夭折与失效恢复子模块负责夭折组合服务实例并进行失效恢复。
其具体步骤为:
S2.3.1调用失效恢复模块,生成用于补偿并撤销其执行结果的服务/组合服务,将该服务/组合服务提交到待调度组合服务队列中;
S2.3.2撤销组合服务CSi中已执行服务实例获得的执行凭证;
S2.3.3将CSi从REC或NREC集中移出。
S2.4当组合服务实例CSi完成给定任务,发出提交请求时,并发调度模块的组合服务提交子模块被激活,完成CSi的提交。提交的步骤为:
S2.4.1如果Sij与某个CSk的一个获取了执行凭证的服务实例Skl冲突,且TS(CSi)> TS(CSk),那么CSi进入等待状态,直至CSk结束;
S2.4.2撤销已执行服务实例所获得的执行凭证;
S2.4.3将CSi从REC集或NREC集中移出。
以上所述仅是本发明的优选实施方式,本发明的保护范围并不仅局限于上述实施例,凡属于本发明思路下的技术方案均属于本发明的保护范围。应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理前提下的若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。