代码之家  ›  专栏  ›  技术社区  ›  Serj Lotutovici

Activiti-如何同步用户任务

  •  1
  • Serj Lotutovici  · 技术社区  · 11 年前

    我有一个Activiti流,它有一个用户任务部分,如下所示:

    Flow Screen

    基本思想是“等待通知”用户任务等待来自特殊队列的响应。但实际上,一个特定的代码正好完成了任务:

    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("KEY", variable);
    
    String assignee = variable.getAssignee();
    processService.completeTask(assignee, variables);
    

    所以我的问题是,负责此代码的服务可以从该队列接收多个响应。这是我想要的行为(队列可以返回类似Message_Processed的消息,几毫秒后返回Message_Send)。但当第二个响应出现时,Activiti引擎抛出一个异常(参见原因),整个流程就会终止。

    Caused by: org.activiti.engine.ActivitiOptimisticLockingException: Task[id=3867, name=Wait for Notification] was updated by another transaction concurrently
    

    所以我要寻找的是:有没有一种方法可以完成一项任务,以某种方式,它可以接受并接受所有的响应,而不是抛出异常。

    1 回复  |  直到 11 年前
        1
  •  2
  •   Martin Schimak    11 年前

    我看到了以下几点:

    1) 您可能需要查看Activiti接收任务。这实际上更适合等待信号到达: http://www.activiti.org/userguide/index.html#bpmnReceiveTask

    2) 您可能会收到OptimisticLockingException,因为您的更新“太快”且同时进行。这里我看到了选项

    • 您可以以一种方式配置队列使用者,以便它可以以单线程独占方式从队列接收消息。然后,您还应该确保后续的“UpdateMessageVO”服务任务以及接收任务 标记为async=true。这将确保您将向接收任务发出继续的信号,并在同一数据库事务中再次创建一个新的接收任务,以备下一条消息更新。

    • 让队列使用者“崩溃”,出现乐观锁定异常,并确保与队列生产者的事务会话回滚或明确要求重新传递,以便根据某些重新传递策略重新传递消息。

    3) OptimisticLockingException的另一个原因可能是缓存了旧的/更新的任务,而不是在发出继续的信号之前立即查询它。始终这样做,这样就不会“重用”任何过时的任务或执行对象