This topic applies only to the IBM Business Process Manager Advanced configuration.

长时间运行的 BPEL 流程的事务行为

长时间运行的 BPEL 流程跨多个事务运行。每个事务由 Java™ 消息传递服务 (JMS) 消息触发, 或由基于工作管理器的实施触发。

概述

下图说明长时间运行流程中的每个导航步骤如何在它自己的事务中执行。一个导航步骤可以跨多个活动,如调用了服务的调用活动所示。另外,一个事务中也可以运行多个活动,只要未发生事务故障即可。有关事务故障的更多信息,请参阅从事务故障恢复.

此图说明长时间运行流程的每个导航步骤如何在它自己的事务中执行。

为了跨事务边界进行导航,流程实例及其活动实例的状态保存在数据库中。您可以使用事务行为属性来更改事务边界。但是,Business Process Choreographer 可以随时添加或除去事务边界。

通常,在下列情况下需要事务边界:
  • 在等待外部请求时,即,在流程导航期间到达接收活动或检取活动(也称为接收选项活动),但尚未接收到该活动的相应请求时
  • 在为等待活动安排计时器时
  • 在使用调用活动以异步方式调用服务时
  • 在调用人员任务活动时
此外,Business Process Choreographer 还在以下情况下动态引入了事务边界。
  • 在流程导航期间发生故障时
  • 在以同步方式调用未参与流程事务的服务的调用活动启动前后
  • 向子流程传播生命周期操作时,例如当暂挂父流程时,也会在后续事务中暂挂其子流程。
  • 在流程完成后要自动删除流程实例时
  • 在尝试从导致跨一系列活动的事务回滚的故障进行恢复时
  • 在使用事务行为属性指定要引入事务边界时
注:
  • 您的流程设计不应依赖这些边界,因为这些边界可能会在流程导航期间遭到覆盖或在日后做出更改。
  • 事务边界的动态引入也可能影响 API 的行为,例如,completeAndClaimSuccessor。在此示例中,如果在下一个人员任务前面动态引入事务边界,那么 API 请求将返回而不进行声明。

修改事务边界

当执行业务流程建模时,您可以通过更改活动的事务行为属性为某些类型的活动(如调用、片段和人员任务活动)提供事务边界建议。如果调用活动调用了未参与当前事务的同步服务,那么将忽略事务行为属性。对于这种情况,在调用活动启动前以及调用活动完成后,始终存在事务边界。

此属性可以具有下列其中一个值:
在此之前落实
落实当前事务,然后启动新事务。具有此属性值的活动将成为新事务的第一个活动。
在此之后落实
此活动参与当前事务。在此活动成功完成后,落实事务,然后启动新事务。对于紧跟其后的每个活动都将启动一个新事务,因此每个后续活动都将成为其中一个新事务中的第一个活动。
参与
此活动参与当前事务。不会在此活动前后设置其他事务边界。
在下列情况下,此设置允许事务根据后续活动的事务行为属性设置值继续对这些活动进行导航。
  • 如果调用活动以同步方式调用服务,那么响应消息到达时,将触发新事务。事务很短暂,因为更新调用活动状态后会立即落实事务。
  • 在人员任务活动序列中,每个人员任务活动需要两个事务,其中一个事务用于激活该人员任务活动,另一个事务用于完成该人员任务活动。如果将此设置更改为参与,那么可以将事务数减少为每个人员任务活动一个事务。这是因为会在同一个事务中完成前一个人员任务活动并激活下一活动。
  • 启用使用 completeAndClaimSuccessor API 的服务器控制页面流。
需要自己的事务
此活动在它自己的事务中运行。这意味着,此活动启动前将落实当前事务,此活动完成后将启动新事务。
您还可以通过更改相应活动的事务行为属性,确定是在接收活动后还是在接收选择(选取)活动的接收操作完成后落实用于启动流程的事务。为了启动接收活动和接收选择活动,属性可以具有下列其中一个值:
在此之后落实
在此活动成功完成后,落实用于启动流程的事务,然后启动新事务。如果您使用同步 API 调用来调用流程实例,此设置很有用。
参与
完成活动后,用于启动流程的事务仍继续运行。如果要使用 initiateAndClaimFirst API 调用流程实例,那么需要使用此设置。您可以使用此 API 创建流程实例并立即声明第一个人员任务。
如果您的流程调用另一个 BPEL 流程,请确保相应调用活动不属于启动流程的事务。您可以通过使用以下方式之一设置事务行为属性来实现这一目标:
  • 将启动接收活动或接收选择活动的属性设置为在此之后落实
  • 将调用活动的属性设置为在此之前落实需要自己的事务

对流程活动中的并行分支进行并发导航

要对流程活动中的并行分支进行并发导航,在每个分支开头都需要新的事务边界,以便在独立的事务中处理每个并行活动。这意味着,必须将每个并行分支中第一个活动的事务行为属性设置为在此之前落实需要自己的事务,以便从此流程的开头实现并行性。

注: 对于 Oracle 数据库,流程实例中并行分支的导航事务已进行序列化,换言之不能并行运行这些事务。这是因为数据库条目的锁定的颗粒度不像诸如 DB2® 数据库之类的系统那样精细。但是,此类并行分支以异步方式触发的服务仍以并行方式运行;对于这些数据库系统而言,仅对流程导航进行序列化。

并行 forEach 活动分支的并发导航

并行 forEach 活动各分支的处理过程均从自己的独立事务开始。因此,将对这些分支启用并行执行。

注: 对于 Oracle 数据库,流程实例中并行分支的导航事务已进行序列化,换言之不能并行运行这些事务。这是因为数据库条目的锁定的颗粒度不像诸如 DB2 数据库之类的系统那样精细。但是,将并发执行并行 forEach 活动分支上的异步服务,因此可以实现并行性 forEach 活动。

长时间运行流程中的被调用服务和事务

在长时间运行流程中使用调用活动调用的服务既可以参与该长时间运行流程的当前事务,也可以在它自己的事务中运行。

下列设置确定该服务是参与长时间运行流程的事务还是在它自己的事务中运行。
  • 用于调用该服务的交互样式。
    交互样式可以是同步调用或异步调用。该样式由目标 SCA 组件或 SCA 导入的首选交互样式决定,如下表所示:
    表 1.
    目标组件或导入的首选交互样式 单向操作 请求-响应操作
    任意 异步调用 异步调用
    同步方式 同步调用 同步调用
    异步 异步调用 异步调用
  • 对该流程以及所调用服务指定的服务组件体系结构 (SCA) 事务限定符:
    • 对流程组件的引用指定的 suspendTransaction 限定符确定,该流程的事务上下文是否传播到所要调用的服务。
    • 对服务接口指定的 joinTransaction 限定符确定,如果传播事务的话,服务是否参与其调用者的事务。

      根据所设置交互样式和 SCA 限定符的不同,下列规则适用于所调用的服务:

      同步调用
      joinTransaction suspendTransaction = true suspendTransaction = false
      joinTransaction = true 此服务不参与长时间运行流程的事务 此服务参与长时间运行流程的事务
      joinTransaction = false 此服务不参与长时间运行流程的事务 此服务不参与长时间运行流程的事务

      如果某个服务参与长时间运行流程的当前事务,那么仅当落实当前事务时,才会保存该服务对事务资源所作的更改。

      异步调用
      服务始终在自己的事务中运行。

从事务故障恢复

长时间运行的流程中的事务可能出于各种原因回滚,如:
  • 服务器停运,例如由电源故障导致的服务器停运。重新启动服务器时,事务回滚。
  • Business Process Choreographer 基础结构故障,例如导致成功服务调用回滚的死锁。Business Process Choreographer 使用其内部队列处理该故障。有关更多信息,请参阅事务回滚时恢复成功的服务调用
  • 从流程调用的服务强制实施回滚。有关更多信息,请参阅恢复导致运行时异常的服务调用

事务回滚时恢复成功的服务调用

恢复行为取决于所调用服务是否参与当前事务。

某个调用活动调用了参与当前事务的服务。该服务的执行已完成。该服务完成后,如果发生错误,并且该事务回滚到流程在该事务启动前所处的状态,那么还将回滚所调用服务的效果。再次尝试该事务时,将再次调用该服务。

相反,如果所调用服务未参与当前事务,并且该服务返回了响应,那么该响应将存储在独立的事务中。如果存储该响应后发生错误,那么将回滚并重试当前事务。但是,在重试期间不会再次调用该服务,而是恢复所存储的响应并继续进行导航。

恢复导致运行时异常的服务调用

如果由于服务调用抛出运行时异常导致事务失败并强制实施回滚,那么触发该事务的消息仍将留在 JMS 导航的 Business Process Choreographer 内部队列或工作管理器中,同时消息重试次数增加 1。重试行为取决于该事务包含单一活动还是跨多个活动。
包含单一活动的事务
在新事务中重试该活动。
跨多个活动的事务
重试该事务时,将缩小事务边界,以便在完成各活动后落实该事务。这样,可以缩小故障范围以定位导致异常的活动。
缩小事务边界的示例
一个事务步骤跨多个活动 {A1 到 An}。如果活动 An 返回运行时异常,且该事务标记为待回滚,事务边界将被缩小至 {A1} 和 {A2 到 An}。如果活动 An 再次返回运行时异常,事务边界现将缩小至 {A2} 和 {A3 到 An}。重复此类事务边界调整,直至活动 An 在自己的事务 {An} 中运行为止。如果活动 An 仍然返回运行时异常,且该事务标记为待回滚,那么异常将存储到本地事务中。重试 {An} 事务期间,无需再次调用活动 An 实现即可获取异常信息。

活动 An 的后续处理取决于该活动的发生未处理的故障时继续处理设置的值。

提示: 如果要在单一事务中始终调用长时间运行的流程中的一系列活动,那么需要将这些活动的业务逻辑提取到微流程中,然后作为子流程进行调用。微流程的逻辑始终在单一事务中运行。