cancel
Showing results for 
Search instead for 
Did you mean: 

Externalizing Transaction Management for Activiti

aseem
Champ in-the-making
Champ in-the-making
Hi,

Is there a way to tell Activiti to use an external transaction manager for managing transactions within a bean? I've gone through the documentation and other posts on this forum and it seems like if we mark our UserBean with @Transactional (Spring annotation) and set transactionsExternallyManaged to true, we can let activiti know that the transactions are being managed externally.

The app that I'm working on doesn't use Spring, but guice-persist to manage transactions at http session level. Is there a way for activiti (5.14) to know about that?


@com.google.inject.persist.Transactional(rollbackOn = Exception.class)
public void doStuff()
{
     service1.method1();
     workflowSvc.someMethod();            //Activiti processing - call to one of the services in activiti
     service1.method2();
}


If service1.method2() throws an Exception, changes to Activiti tables should be rolledback also (since its wrapped within a transaction) that is managed by guice-persist.

One way we can think of is to extend from what SpringProcessEngineConfiguration is doing to let Activiti know that we're using an external transactionManager and implement our own process engine configuration class which defines the transactionManager in properties. Thoughts?
4 REPLIES 4

jbarrez
Star Contributor
Star Contributor
That is indeed the way to do it: create a custom config and let you be inspired by the the SpringEngineConfiguration.
The bulk of the work will probably be the interceptor responsible for starting/committing the transaction.

aseem
Champ in-the-making
Champ in-the-making
Thanks Joram, will try to implement and let you know how it goes. Alternatively, will let you know in case I get stuck Smiley Wink

aseem
Champ in-the-making
Champ in-the-making
I was successful in doing this (which was a while ago) and sharing the solution in case someone else runs into this kind of a problem. Its a bit late, especially since 5.16 was released which handles this in a very graceful manner.

Had to create a CustomProcessEngineConfiguration class that extends ProcessEngineConfigurationImpl and overrides createTransactionInterceptor() and buildProcessEngine() methods.

<code>
@Singleton
public class CustomProcessEngineConfiguration extends ProcessEngineConfigurationImpl
{
    @Override
    protected CommandInterceptor createTransactionInterceptor()
    {
        return new TransactionInterceptor(this.getDataSource());
    }

    @Override
    public ProcessEngine buildProcessEngine()
    {
        return super.buildProcessEngine();
    }
}
</code>

The TransactionInterceptor class extends AbstractCommandInterceptor (for 'next' variable to execute the transaction chain) and implements org.aopalliance.intercept.MethodInterceptor. The overridden invoke(MethodInvocation invocation) method is what manages the starting and committing of transactions or rolling back in case of failure. In my case, it was as easy as looking at methods which have @com.google.inject.persist.Transactional annotation on them and wrapping them up in one transaction in the invoke() method.

On definition side, setting transactionsExternallyManaged to true in activiti.cfg.xml and creating process engine as:

<java>
ProcessEngine processEngine = CustomProcessEngineConfiguration
                .createProcessEngineConfigurationFromResource("activiti.cfg.xml")
                .setDataSource(dataSource)
                .buildProcessEngine();
</java>

did the trick.

jbarrez
Star Contributor
Star Contributor
Thanks for posting back, even after this time 🙂