如何使用 REST API 以原子方式修改变量
How to modify variables in an atomic way using REST API
考虑一个当前具有某些值的流程实例变量。我想更新它的值,例如使用 Activiti / Camunda 的 REST API 将它加一。你会怎么做?
问题在于 REST API 具有设置变量值和获取变量值的服务。但是合并这样的 API 很容易导致竞争条件。
还要考虑到我的示例是关于整数的,而变量可以是复杂的 JSON 对象或数组!
此答案适用于 Camunda 7.3.0:
没有开箱即用的解决方案。您可以执行以下操作:
- 使用实现变量修改端点的自定义资源扩展 REST API。由于 Camunda REST API 使用 JAX-RS,因此可以将 Camunda REST 资源添加到自定义 JAX-RS 应用程序。详见[1]。
在自定义资源端点中,使用自定义命令在一个事务中实现读取-修改-写入循环:
protected void readModifyWriteVariable(CommandExecutor commandExecutor, final String processInstanceId,
final String variableName, final int valueToAdd) {
try {
commandExecutor.execute(new Command<Void>() {
public Void execute(CommandContext commandContext) {
Integer myCounter = (Integer) runtimeService().getVariable(processInstanceId, variableName);
// do something with variable
myCounter += valueToAdd;
// the update provokes an OptimisticLockingException when the command ends, if the variable was updated meanwhile
runtimeService().setVariable(processInstanceId, variableName, myCounter);
return null;
}
});
} catch (OptimisticLockingException e) {
// try again
readModifyWriteVariable(commandExecutor, processInstanceId, variableName, valueToAdd);
}
}
有关详细讨论,请参阅 [2]。
[1] http://docs.camunda.org/manual/7.3/api-references/rest/#overview-embedding-the-api
[2] https://groups.google.com/d/msg/camunda-bpm-users/3STL8s9O2aI/Dcx6KtKNBgAJ
考虑一个当前具有某些值的流程实例变量。我想更新它的值,例如使用 Activiti / Camunda 的 REST API 将它加一。你会怎么做?
问题在于 REST API 具有设置变量值和获取变量值的服务。但是合并这样的 API 很容易导致竞争条件。
还要考虑到我的示例是关于整数的,而变量可以是复杂的 JSON 对象或数组!
此答案适用于 Camunda 7.3.0:
没有开箱即用的解决方案。您可以执行以下操作:
- 使用实现变量修改端点的自定义资源扩展 REST API。由于 Camunda REST API 使用 JAX-RS,因此可以将 Camunda REST 资源添加到自定义 JAX-RS 应用程序。详见[1]。
在自定义资源端点中,使用自定义命令在一个事务中实现读取-修改-写入循环:
protected void readModifyWriteVariable(CommandExecutor commandExecutor, final String processInstanceId, final String variableName, final int valueToAdd) { try { commandExecutor.execute(new Command<Void>() { public Void execute(CommandContext commandContext) { Integer myCounter = (Integer) runtimeService().getVariable(processInstanceId, variableName); // do something with variable myCounter += valueToAdd; // the update provokes an OptimisticLockingException when the command ends, if the variable was updated meanwhile runtimeService().setVariable(processInstanceId, variableName, myCounter); return null; } }); } catch (OptimisticLockingException e) { // try again readModifyWriteVariable(commandExecutor, processInstanceId, variableName, valueToAdd); } }
有关详细讨论,请参阅 [2]。
[1] http://docs.camunda.org/manual/7.3/api-references/rest/#overview-embedding-the-api
[2] https://groups.google.com/d/msg/camunda-bpm-users/3STL8s9O2aI/Dcx6KtKNBgAJ