Skip to main content

Activiti 依赖事务监听器(下)


Activiti 依赖事务监听器

Activiti依赖事务监听器(上)讲解了Activiti依赖事务监听器的概念,接下来看一下该如何使用TransactionDependentExecutionListener。

当引擎解析BPMN XML模型的Java模型的“常规”执行/任务听众会转换为ActivitiListeners事务相关的监听器。如果引擎操作的执行期间,遇到ActivitiListener要检查它是否一个事务依赖。如果是这样,它不执行它那一刻,就像它与其他听众,它计划为以后处理。

这种延迟处理需要拍摄快照依此当前的执行状态,因为事情可以改变实际执行侦听器之前。甚至更重要的是,执行本身执行侦听器时不再可用。

(关于这一点涉及到了源码的讲解,后续章节会详细的讲解)。

让我们看一下如何使用该接口。

首先定义一个流程文档,该流程文档对应的图如下所示:

上图对应的流程文档XML内容如下所示:

 <process id="transaction-dependent-listeners">

     <startEvent id="start">

         <extensionElements>

             <activiti:executionListener delegateExpression="${myActivityLogger}" event="start" />

         </extensionElements>

     </startEvent>



     <sequenceFlow id="flow1" sourceRef="start" targetRef="script-task-1"/>

     <scriptTask id="script-task-1" name="Script Task One" activiti:async="true" scriptFormat="groovy">

         <extensionElements>

             <activiti:executionListener delegateExpression="${myActivityLogger}" event="start" />

             <activiti:executionListener delegateExpression="${myMessageProducer}" event="start" onTransaction="committed" />

         </extensionElements>

         <script>

            println 'script task one; start new transaction'

         </script>

     </scriptTask>

     <sequenceFlow id="flow2" sourceRef="script-task-1" targetRef="receive-task-1"/>

     <receiveTask id="receive-task-1" name="Wait">

         <extensionElements>

             <activiti:executionListener delegateExpression="${myActivityLogger}" event="start" />

         </extensionElements>

     </receiveTask>

     <sequenceFlow id="flow3" sourceRef="receive-task-1" targetRef="script-task-2"/>

     <scriptTask id="script-task-2" name="Script Task Two" activiti:async="true" scriptFormat="groovy">

         <extensionElements>

             <activiti:executionListener delegateExpression="${myActivityLogger}" event="start" />

         </extensionElements>

         <script>

            println 'script task two; start new transaction'

         </script>

     </scriptTask>

     <sequenceFlow id="flow4" sourceRef="script-task-2" targetRef="end"/>

     <endEvent id="end">

         <extensionElements>

             <activiti:executionListener delegateExpression="${myActivityLogger}" event="start" />

         </extensionElements>

     </endEvent>

 </process>

当Activiti遇到ReceiveTask执行进入等待状态。这意味着流程实例逗留在在ACT_RU_EXECUTION表中。

假设在上面的示例脚本任务一个的将JMS队列上的消息。和消费者的消息将会发送一个信号流程实例(继续从等待状态)。如果发送信号发生的非常快,等待状态尚未就可能依然存在。这种情况是例外,但它可能发生。

下面看一下JMS的配置:

生产者:

/**

 * @author www.shareniu.com

 */

@Component("myMessageProducer")

public class MyMessageProducer implements TransactionDependentExecutionListener {

    private static final Logger logger = LoggerFactory.getLogger(MyMessageProducer.class);

    @Autowired

    private JmsTemplate jmsTemplate;

    public void notify(String processInstanceId, String executionId, FlowElement currentFlowElement, MapexecutionVariables, MapcustomPropertiesMap) {

        logger.debug("Sending message <{}> to queue", executionId);

        jmsTemplate.convertAndSend("receive_task_signal", executionId);

    }

}

消费者:

/**

 * @author www.shareniu.com

 */

@Component

public class MyMessageConsumer {

    private static final Logger logger = LoggerFactory.getLogger(MyMessageConsumer.class);

    @Autowired

    private RuntimeService runtimeService;

    @JmsListener(destination = "receive_task_signal", containerFactory = "myFactory")

    public void receiveMessage(String executionId) {

        logger.debug("Received message: <" + executionId + ">");

        logger.debug("Signaling execution with id: <" + executionId + ">");

        runtimeService.trigger(executionId);

    }

}

在上面的示例脚本任务一个只是一个占位符标记的开始一个事务。这同样适用于“脚本任务两个”。的脚本任务一个和接收任务“等待”是相同的事务的一部分。这意味着尽管myMessageProducer的侦听器配置的脚本任务一个侦听器将在“等待”是坚持执行。

运行上述的代码,执行如下的脚本即可。

mvn spring-boot:run

控制台的输出如下:

2017-02-07 15:18:52.229 DEBUG 1243900 --- [cTaskExecutor-1] o.a.demo.listener.MyActivityLogger       : Current activity id:

script task one; start new transaction

2017-02-07 15:18:52.653 DEBUG 1243900 --- [cTaskExecutor-1] o.a.demo.listener.MyActivityLogger       : Current activity id:

2017-02-07 15:18:52.657 DEBUG 1243900 --- [cTaskExecutor-1] o.a.demo.listener.MyMessageProducer      : Sending message <5> to queue

2017-02-07 15:18:52.689 DEBUG 1243900 --- [enerContainer-1] org.activiti.demo.jms.MyMessageConsumer  : Received message: <5>

2017-02-07 15:18:52.689 DEBUG 1243900 --- [enerContainer-1] org.activiti.demo.jms.MyMessageConsumer  : Signaling execution with id: <5>

2017-02-07 15:18:52.696 DEBUG 1243900 --- [cTaskExecutor-2] o.a.demo.listener.MyActivityLogger       : Current activity id:

script task two; start new transaction

2017-02-07 15:18:52.703 DEBUG 1243900 --- [cTaskExecutor-2] o.a.demo.listener.MyActivityLogger       : Current activity id: