有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java OptimisticLockingException与Camunda服务任务

我们在Camunda流程中看到以下情况下的乐观锁定例外:

该流程由一个UserTask、一个Gateway和一个ServiceTask组成。用户任务执行

runtimeService.setVariable(execId, "object", out);`. 
taskService.complete(taskId);

以下ServiceTask使用“object”作为输入变量(不修改它),完成后抛出所述OptimisticLockingException。我的问题似乎源于这样一个事实:taskService.complete()在刷新UserTask中设置的变量之前立即执行ServiceTask

我遇到了另一个相关的问题,当我在一个UserTask中执行runtimeService.setVariable(Map<Strong, Boolean>)并试图在该UserTask之后的网关中作为转换守卫访问映射的成员时,发生了这个问题

我发现了以下文章:http://forums.activiti.org/content/urgenterror-updated-another-transaction-concurrently,它似乎与我的问题有关。但是,我不清楚这是否是(非)想要的行为,以及如何从UserTask访问DelegateExecution-对象


共 (2) 个答案

  1. # 1 楼答案

    您可以考虑在服务任务上使用异步继承。这将确保服务任务在新的事务/命令上下文中执行。 考虑读取camunda documentation on transactions and asynchronous continuations

    DelegateExecution对象用于提供对流程实例变量的服务任务(JavaDelegate)实现访问。它并不意味着要从用户任务中使用

  2. # 2 楼答案

    经过漫长而繁琐的搜索,我们认为,我们已经解决了camunda的两个问题,这两个问题(加在一起)导致了原始问题的例外

    1. Camunda使用序列化对象(由字节数组表示)上的equals来确定是否必须将流程变量写回数据库。甚至在只读取变量而不设置变量时也会发生这种情况。由于equals是由数组上的指针标识定义的,因此,如果序列化对象已被多次序列化,则它永远不会被确定为“相等”。我们发现,一个runtimeService.setVariable()completeTask()时会导致四个db更新(一个用于setVariable本身,另三个用于各种camunda内部验证操作)。我们认为这是一个bug,并将向camunda提交bug报告

    2. 显然,设置变量有两种方法。一种方法是使用runtimeService.setVariable(),另一种方法是使用delegateTask/delegateExecution.setVariable()。同时使用这两种方法时存在一些缺陷。虽然我们无法将设置简化为一个简单的单元测试,但我们已经确定了发生异常必须涉及的几个组件:

    2.1我们正在使用TaskListener在任务开始时设置一些上下文变量。此任务侦听器使用runtimeService.setVariable()而不是delegateTask.setVariable()。在我们改变了这一点之后,例外消失了

    2.2我们在任务执行期间使用了(并且仍然使用)runtimeService.setVariable()。在我们切换到completeTask(Variables)并省略了runtimeService.setVariable()调用之后,异常也消失了。然而,这不是一个永久的解决方案,因为我们必须在任务执行期间存储流程变量

    2.3只有当通过delegate<X>.getVariable()方式读取或写入流程变量时(通过我们的代码或通过网关和serviceTasks或completeTask(HashMap)的juel解析的camunda实现中隐含),才会发生异常

    非常感谢您的所有意见