Skip to main content

Activiti 依赖事务监听器(上)


Activiti 依赖事务监听器

Activiti5.x

Activiti5.x版本中可以通过监听器辅助自身的业务操作,比如自定义一个执行监听器,则只需要定义一个类,然后实现org.activiti.engine.delegate.ExecutionListener接口即可。任务监听器需要实现org.activiti.engine.delegate.TaskListene。当然也可以自定义表达式以及委托表达式的方式实现。

当监听器被引擎触发的时候,会自动触发所有不同类型的听众(自定义监听器、内置监听器、历史监听器等)。但是自定义的监听器如果出现异常或者错误,那么这些监听器的结果并不依赖事务,通俗一点的描述就是事务回滚之后监听器会重复的执行,这就完全不对了。用下面的例子对其进行说明:

上图的流程文档如下所示:

   <process id="bookflight" name="Book Flight" isExecutable="true">

   <startEvent id="start-event-1" />

   <sequenceFlow id="flow1" sourceRef="start-event-1" targetRef="book-flight" />

   <serviceTask id="book-flight" name="Book flight" activiti:delegateExpression="${bookFlightBean}" activiti:async="true">

   <extensionElements>

   <activiti:executionListener event="end" delegateExpression="${emailBean}"/>

   </extensionElements>

  </serviceTask>

  <sequenceFlow id="flow2" sourceRef="book-flight" targetRef="charge-credit-card">

  </sequenceFlow>

  <serviceTask id="charge-credit-card" name="Charge credit card" activiti:delegateExpression="${chargeCCBean}">

  </serviceTask>

  <sequenceFlow id="flow3" sourceRef="charge-credit-card" targetRef="do-something-else" />

  <serviceTask id="do-something-else" name="Do something else" activiti:delegateExpression="${doSomethingBean}" activiti:async="true">

  </serviceTask>

  <sequenceFlow id="flow4" sourceRef="do-something-else" targetRef="end-event-1" />

  <endEvent id="end-event-1" />

  </process>

假设我们想发送电子邮件预订航班时,信用卡被指控成功。这当然可以以不同的方式来完成的。但是对于本例的缘故我们会通过实现执行侦听器和配置它的‘结束’事件的书飞行活动。

部署并启动上述的流程文档,活动成功。配置的执行侦听器会实现触发和发送电子邮件。

然后收取信用卡的活动执行。这导致一个例外。事务回滚和“书飞行”和“收取信用卡”将再次执行。这意味着我们执行侦听器也将再次执行。

这只是一个简单的例子。并且有许多用例中,您想要侦听器每次执行。但在有些情况下,比如在上面的示例中需要有可能让监听器基于整个事务的结果。比如事务成功,则监听器中的业务逻辑触发,事务失败则监听器中的业务逻辑不应该被触发。

Activiti 6.x

Activiti6中已经提供了事务监听器,以下代码片段显示了一个适应上面的例子,现在与事务相关的执行侦听器配置。

   <serviceTask id="book-flight" name="Book flight" activiti:delegateExpression="${bookFlightBean}" activiti:async="true">

   <extensionElements>

   <activiti:executionListener event="end" delegateExpression="${emailBean}" onTransaction="committed" />

   </extensionElements>

   </serviceTask>

上述代码中,可以通过设置executionListener元素中的onTransaction属性进行事务状态的的定义,即事务的状态监听器的执行以来事务的状态。onTransaction属性可以有如下三个值:

&middot;           Committed(提交)

&middot;           rolled-back(回滚)

&middot;           before-commit(提交前)

注意:Activiti5.X设计器不支持设置onTransaction属性的设置。

新接口

依赖事务执行监听器

依赖事务监听器必须实现一个不同的接口而不是“普通”执行侦听器。TransactionDependentExecutionListener接口提供了一种方法,需要自行实现。该接口的定义如下所示:

public interface TransactionDependentExecutionListener extends BaseExecutionListener {

  String ON_TRANSACTION_BEFORE_COMMIT = "before-commit";

  String ON_TRANSACTION_COMMITTED = "committed";

  String ON_TRANSACTION_ROLLED_BACK = "rolled-back";

 

  void notify(String processInstanceId, String executionId, FlowElement flowElement,

              MapexecutionVariables, MapcustomPropertiesMap);

}

依赖事务任务监听器

对于依赖事务任务监听器TransactionDependentTaskListener接口的定义如下:

   public interface TransactionDependentTaskListener extends BaseTaskListener {

     String ON_TRANSACTION_COMMITTING = "before-commit";

     String ON_TRANSACTION_COMMITTED = "committed";

     String ON_TRANSACTION_ROLLED_BACK = "rolled-back";

     void notify(String processInstanceId, String executionId, Task task, MapexecutionVariables, MapcustomPropertiesMap);

   }

对于最后一个输入参数customPropertiesMap,他是可选的。可以提供一个configureable属性解析器。(参考下文的ReceiveTask示例)。

Activiti 依赖事务监听器(下)