盘古BPM体验地址    盘古BPM交流群盘古BPM交流群号:963222735

Activiti依赖事务监听器(上)

Activiti 分享牛 8999℃

1.1  Activiti5.X

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

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

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

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

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

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

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

5.   <extensionElements>

6.   <activiti:executionListener

7.   event="end"

8.   delegateExpression="${emailBean}"/>

9.   </extensionElements>

10.  </serviceTask>

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

12.  </sequenceFlow>

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

14.  </serviceTask>

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

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

17.  </serviceTask>

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

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

20.  </process>

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

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

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

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

1.1  Activiti 6

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

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

2.   <extensionElements>

3.   <activiti:executionListener

4.   event="end"

5.   delegateExpression="${emailBean}"

6.   onTransaction="committed" />

7.   </extensionElements>

8.   </serviceTask>

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

&middot;           Committed(提交)

&middot;           rolled-back(回滚)

&middot;           before-commit(提交前)

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

1.2  新接口

1.2.1           依赖事务执行监听器

依赖事务监听器必须实现一个不同的接口而不是&ldquo;普通&rdquo;执行侦听器。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);

}

1.2.2           依赖事务任务监听器

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

1.   public interface TransactionDependentTaskListener extends BaseTaskListener {

2.    

3.     String ON_TRANSACTION_COMMITTING = "before-commit";

4.     String ON_TRANSACTION_COMMITTED = "committed";

5.     String ON_TRANSACTION_ROLLED_BACK = "rolled-back";

6.    

7.     void notify(String processInstanceId, String executionId, Task task,

8.             MapexecutionVariables, MapcustomPropertiesMap);

9.   }

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

Activiti依赖事务监听器(下) 


转载请注明:分享牛 » Activiti依赖事务监听器(上)