Hi Thorben,
thanks for the info! I was playing with this approach today.
-
Listening for TransactionState.COMMITTING
TransactionListener transactionListener = commandContext -> {
logger.debug(“TransactionState.COMMITTING”);
BpmMessage message = createMessage(eventType, event);
if (message != null) {
sendJmsMessage(eventType, message, getTopic(event));
}
};
Context.getCommandContext().getTransactionContext().addTransactionListener(TransactionState.COMMITTING, transactionListener);
The nice thing about using a TransactionListener on COMMITTING is, that I am still inside of the transaction, so I can just call other EJB methods without having to worry about that stuff.
This works well for tasks: a newly created task has been persisted at this point and I can find it. So this solves half of my problem. Unfortunately it doesn’t work for processes. Is this by design or is the notification sent a bit to early?
- Listening for TransactionState.COMMITTED
Using this variation I get an exception because “The transaction is not active!”.
Caused by: de.emsw.gosa.bpm.engine.BpmException: com.arjuna.ats.jta.exceptions.InactiveTransactionException: ARJUNA016102: The transaction is not active! Uid is 0:ffffc0a8a897:64cc545d:578dffa8:198
at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.setRollbackOnly(TransactionImple.java:306)
at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.setRollbackOnly(BaseTransaction.java:159)
at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.setRollbackOnly(BaseTransactionManagerDelegate.java:123)
at org.camunda.bpm.engine.impl.interceptor.JtaTransactionInterceptor.doRollback(JtaTransactionInterceptor.java:141)
at org.camunda.bpm.engine.impl.interceptor.JtaTransactionInterceptor.execute(JtaTransactionInterceptor.java:60)
at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:66)
at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
at org.camunda.bpm.engine.impl.AbstractQuery.singleResult(AbstractQuery.java:130)
at de.emsw.gosa.bpm.engine.BpmUtilBean.getProcess(BpmUtilBean.java:40)
If I use the TransactionManager to create my own transaction inside of the listener like this
TransactionListener transactionListener = commandContext -> {
logger.debug("TransactionState.COMMITTED");
try {
transactionManager.begin();
try {
BpmMessage message = createMessage(eventType, event);
if (message != null) {
sendJmsMessage(eventType, message, getTopic(event));
}
} finally {
transactionManager.commit();
}
} catch (Exception e) {
e.printStackTrace();
}
};
Context.getCommandContext().getTransactionContext().addTransactionListener(TransactionState.COMMITTED, transactionListener);
I get an exception that the “thread is already associated with a transaction”:
12:30:41,790 ERROR [stderr] (EJB default - 3) javax.transaction.NotSupportedException: BaseTransaction.checkTransactionState - ARJUNA016051: thread is already associated with a transaction!
12:30:41,790 ERROR [stderr] (EJB default - 3) at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.begin(BaseTransaction.java:72)
12:30:41,790 ERROR [stderr] (EJB default - 3) at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.begin(BaseTransactionManagerDelegate.java:65)
12:30:41,790 ERROR [stderr] (EJB default - 3) at de.emsw.gosa.bpm.message.BpmMessageBean.lambda$0(BpmMessageBean.java:90)
12:30:41,790 ERROR [stderr] (EJB default - 3) at org.camunda.bpm.engine.impl.cfg.jta.JtaTransactionContext$TransactionStateSynchronization.afterCompletion(JtaTransactionContext.java:104)
I’m not sure how to continue here. I realize that this is probably out of the scope of the process engine and more of a JavaEE issue, but if you have any further ideas I would be glad to hear them.
Smile,
Christoph