Description of problem: Platform issue for JBPM-4031
Martin Weiler <mweiler> made a comment on jira JBPM-4031 Proposal to fix this issue: {code} diff --git a/core/src/main/resources/org/jbpm/context/exe/ContextInstance.hbm.xml b/core/src/main/resources/org/jbpm/context/exe/ContextInstance.hbm.xml index 300a612..d0fd5ab 100644 --- a/core/src/main/resources/org/jbpm/context/exe/ContextInstance.hbm.xml +++ b/core/src/main/resources/org/jbpm/context/exe/ContextInstance.hbm.xml @@ -10,7 +10,7 @@ extends="org.jbpm.module.exe.ModuleInstance" discriminator-value="C"> - <map name="tokenVariableMaps" cascade="all" inverse="true"> + <map name="tokenVariableMaps" cascade="all" inverse="true" optimistic-lock="false"> <!-- add on-delete for optimized deletion <key column="CONTEXTINSTANCE_" on-delete="cascade" /> --> {code} This fix prevents the ContextInstance version to be incremented during the update of the TokenVariableMap. As a result, the process execution is no longer failing with a race condition. But there is a caveat: if all nodes inside the fork/join are async with no wait states, the parent node will not be signaled automatically out of the join when all child tokens arrive.
Created attachment 765213 [details] Added stack trace (from support case).
Marco Rietveld <marco.rietveld> made a comment on jira JBPM-4031 I've looked at a bunch of different hibernate 3 mapping options, and started to look at possible hibernate session tricks (tx synchs? session.refresh()?), but luckily, I ran into JBPM-2948, which Brad Davis implemented. One possible solution for this user would be to implement his process using the functionality described there, which basically means using async subprocesses instead of async nodes. I'll let you know when I have a working test for this.
Toshiya Kobayashi <tkobayas> made a comment on jira JBPM-4031 Hi Marco, How about this fix? (attached as JBPM-4031.patch) {code:java} diff --git a/core/src/main/java/org/jbpm/context/exe/ContextInstance.java b/core/src/main/java/org/jbpm/context/exe/ContextInstance.java index 322ae11..c15b4a6 100644 --- a/core/src/main/java/org/jbpm/context/exe/ContextInstance.java +++ b/core/src/main/java/org/jbpm/context/exe/ContextInstance.java @@ -330,7 +330,7 @@ public class ContextInstance extends ModuleInstance { return tokenVariableMap; } - private TokenVariableMap createTokenVariableMap(Token token) { + public TokenVariableMap createTokenVariableMap(Token token) { if (tokenVariableMaps == null) { tokenVariableMaps = new HashMap(); } diff --git a/core/src/main/java/org/jbpm/graph/node/Fork.java b/core/src/main/java/org/jbpm/graph/node/Fork.java index 026443c..7229be4 100644 --- a/core/src/main/java/org/jbpm/graph/node/Fork.java +++ b/core/src/main/java/org/jbpm/graph/node/Fork.java @@ -115,6 +115,8 @@ public class Fork extends Node { if( ! parentChildTokens.containsKey(transitionName)) { parentChildTokens.put(transitionName, childToken); } + // JBPM-4031 : Create TokenVariableMap for each child token beforehand + executionContext.getContextInstance().createTokenVariableMap(childToken); } // phase three: branch child tokens from the fork into the transitions {code} I have verified it with JBPM4031Test.testVariablesAfterFork() and manual test in SOA-P 5.3.1.
Toshiya Kobayashi <tkobayas> made a comment on jira JBPM-4031 ContextInstance.getOrCreateTokenVariableMap() is not useful in this case because it returns TokenVariableMap of its parent token. So I use createTokenVariableMap() instead.
Marco Rietveld <marco.rietveld> made a comment on jira JBPM-4031 I've applied to the patch to the code and tested it. It's good!
Marco Rietveld <marco.rietveld> updated the status of jira JBPM-4031 to Resolved