cancel
Showing results for 
Search instead for 
Did you mean: 

Activiti transaction + JEE transactions

jsher
Champ in-the-making
Champ in-the-making
Hi,

Apologies for these basic questions - I have limited JEE knowledge, but here goes…

I am trying to build a picture of how Activiti will behave in a JEE setting, particularly from a persistence/transactions point of view. I am considering only JEE6 container managed persistence for the moment. I see a couple of different types of interactions and process flows in this regard…

1. Session bean service method invoked in a CMP transaction. Bean invokes Activiti (RS.startProcess(), RS.signal(), TS.complete(), etc). Process executes a JavaDelegate task which in turn invokes methods on EJBs, then reaches a wait state at which changes are persisted.
Q1 - Am I correct in saying that if I use JtaProcessEngineConfiguration, transactionsExternallyManaged=true, and configure data sources appropriately then all persistence operations performed by Activiti will be done in the same transaction as the EJB CMP ?
Q2 - If the answer to the previous is yes, would I be correct in saying that the security context (principal, etc) would be propagated from the initiating session bean, via Activiti, to the EJB invoked by the delegate task ?

2. My process uses a timer or async continuation in which case Activiti executes subsequent tasks in a JobExecutor thread. These tasks may invoke EJBs.
Q3 - How can we avoid violating JEE restriction on managing threads outside of control of the container ?
Q4 - How can execution of these tasks be made to participate in a CMP transaction ? I can't see anything in doc or code to help deal with this. I have read a bit of how jBPM provides for JMS queue for async and I assume this is how jBPM deals with this, and since I understand that Activiti and jBPM share a common heritage I was expecting to see something similar for Activiti.

I'd appreciate some help in answering these questions.

Thanks
    James
14 REPLIES 14

jsher
Champ in-the-making
Champ in-the-making
Hi James,

I will merge branch ACT-34 shortly, that will make it a lot easyer to implement JobExecutor delegating to Threads of your choice (ie. "supported", Container-Managed Threads in an App Server)

Daniel, will these scheme work for jobs initiated by timer events (boundary, intermediate) ? What I mean is we need to have Activiti continue to execute tasks which flow from timer events as it does currently but to do so in CM threads. The custom JobExecutor would only provide CM thread to Activiti when timer event fires, Activiti then continues to execute the flow as defined in the process.

Does this make sense ?

Regards
   James

pkonyves
Champ in-the-making
Champ in-the-making
Hi,

This topic is useful but I'm still unsure about the behaviour of Activiti in regard to JTA Transactions. I have the same setup as the original poster's:
JtaProcessEngineConfiguration, transactionsExternallyManaged=true

some part of my process definition setup is such:
+—————————————————–+
|  user_task_a –> service_task –> user_task_b       |
|                                                     +—+
|    [Error boundary event]                           |   |
+————-|—————————————+   |
              |                                           |
              +–>handle_error—————————-+–>O

In the JavaDelegate of service_task I call EJB methods with default transaction attribute: Required.

Q1) When I complete user_task_a from Activiti GUI will I have a started transaction in the service_task?
Q2) When I complete user_task_a from code in my own service layer, will I have a transaction in the service_task?
Q3) When I complete user_task_a from code within EJB that started a transaction, will activiti use this transaction or create a new one?

Q4) If There is already a started transaction in the service_task – assumingly activiti already started one at the completion of user_task_a – in which I invoke the EJB. And EJB throws EJBTransactionRolledBack exception, will it roll back the transaction started by activiti?

My use case is that we have several service tasks, that may generate errors. What we do is we create our process definitions in a subprocess and use an Error boundary event that leads to a "handle error" user task in case any error.
The scenario is this: If something goes wrong in service task, we catch the exception, set a variable and throw a BpmnError exception to fall into the "handle error" task.
My problem is that I don't see right now if an error happens in my EJB that is called from service task, how it will affect the workflow. If the error triggers a transaction rollback, will it roll back the activiti transaction as well and eventually the state won't change?

My solution would be this to my problem: I would set the transactionAttribute of my EJB called from service task to "requiresNew". This way if something goes wrong in the EJB, it will not affect the activiti transaction.

Any suggestions about this approach?

Thank you for your help!

frederikherema1
Star Contributor
Star Contributor
  • Q1: Yes, activiti will request a new transaction from the underlying transaction mechanism, in your case, JTA

  • Q2: If your own service-layer uses JTA-transactions, activiti (when completing task) will use the existing JTA-trasaction (underlying transaction-mechanism returns the active one to activiti). If your own service IS NOT transactional, activiti will get a new JTA-transactions as wit Q1.

  • Q3: If the EJB uses JTA, then yes, activiti will participate in this transaction.

  • Q4: That's what JTA is for… If configured correctly (using XA if needed), exceptions in YOUR code or Activiti code will roll back both. So when "completing" a task and an exception is thorn somewhere while executing the process, it's rolled back to the initial state. So the "complete" never happened Smiley Wink
If you're service-calls to EJB and it throws an exception, it's very likely that the proxy around the EJB will cause the transaction to be marked as "rollback only", depending on the configuration of the EJB and the rollback-behaviour. So if you want to have your EJB be rolled back, but you're handling the error inside the process (BPMNError) it makes sense to use a new transaction for the service-call. However, it's not guaranteed that these 2 transactions (in case of success) both get committed… This may cause invalid state in your process vs. your own model

pkonyves
Champ in-the-making
Champ in-the-making
frederikheremans:
Thanks for clearing these up. I'm familiar with JTA in the context of EJBs, but was not sure how it cooperates with activiti.

I'm now concerned about this "it's not guaranteed that these 2 transactions (in case of success) both get committed".
In which cases does not both transactions will be committed? It would be essential to know if I go with this approach.

Do you have a better idea about error handling in service tasks?

frederikherema1
Star Contributor
Star Contributor
If you have 2 transactions, one for activiti, and another one (forced created by the REQUIRES_NEW) for your beans/services. In case the service-call is done, the REQUIRES_NEW transaction is committed. Then, when activiti engine flows on, it's possible that, after the service-task call, something goes wrong (no DB, another service-task fails, optimistic locking, …) the activiti-transaction is rolled back.

This leaves your own services' data-mutations committed and activiti's reverted back to the state it was in, causing a difference. So having your services FORCE a new transaction, is generally a bad idea if you want to be absolutely safe.

Or am I missing something?