here's a status report on the jta transaction interceptor.
goals: configure 1 command service that can handle following situations:
Called from inside an ongoing JTA transaction
The JTA transaction could be started by user code (BMT), ejb with CMT, seam or a spring component.
jBPM should just join this transaction. We assume that hibernate is configured with a JTA TX aware datasource. So in that case our JTA transaction interceptor doesn't have to do anything.
Called without an ongoing JTA transaction
The interceptor will then use the UserTransaction to begin and commit a JTA transaction. In case of a RuntimeException coming out of the command execution, then the JTA UserTransaction is rolled back.
In case this interceptor manages the JTA transaction I also added retry mechanism around the JTA transaction. Which means that if a StaleObjectStateException comes out of hibernate, then the same command is retried. By default max 3 times with incremental backoff delays.
I couldn't leverage the retry interceptor for this feature. As that would mean that the retry interceptor is applied always. And the JtaTransactionInterceptor will not manage the JTA tx all situations. So I had to duplicate that code into the JTA tx interceptor. It's left as a TODO (JBPM-2196) to refactor the code so that the retry code not duplicated.
Another path to investigate further is associating the jBPM Environment to the JTA transaction (JBPM-2197). Suppose a user manages a JTA tx with an EJB method. Inside that method there are 3 subsequent invocations to the jBPM services. In the current configuration, the EnvironmentInterceptor will create 3 separate environments. But we could also do just like hibernate and seam in that case. During interception of the first method invocation, create a new Environment and then associate it to the JTA transaction and close it in the beforeCompletion of a Synchronization. Then the 2 subsequent invocations within the same TX could find and leverage that environment.