In my current project we use Activiti as a business process orchestrator. Recently we ran into problems with database transactions. We had webservice calls to an external in one of process steps (service task). We wanted to have everything committed before the call, just in case the webservice fails. Ideally, every process step should be executed in a separate transaction
We (naively) thought every service task was wrapped into an individual transaction. We discovered that there was one big transaction spanning the entire process.
This blog post is a recording of spikes I did to understand when transactions are started and completed in Activiti processes.
In our Grails application Activiti
ProcessEngine was configured with
SpringProcessEngineConfiguration. It requires a Spring
TransactionManager. We duly supplied the manager created by Grails.
According to the documentation
The ProcessEngineFactoryBean will have added an extra interceptor to the services that applies Propagation.REQUIRED transaction semantics on the Activiti service methods.
* every Activiti service is transactional (
RepositoryService, etc.). It either starts a transaction or participates in an existing one.
RuntimeService is used to launch a process, every service task during the process execution ‘inherits’ the transaction from the
* same transaction for the duration of the process execution
Service tasks – how to get control of transactions?
Mark service classes or individual methods methods as
@Transactional(propagation = Propagation.REQUIRES_NEW).
Note: be careful when mixing process steps participating in the ‘parent’ transaction triggered by the
RuntimeService and those wrapped in their own transaction. If the ‘parent’ transaction is rolled back, individual transactions may be committed. If service tasks with individual transactions depend on some modifications made before (in tasks inside the ‘parent’ transaction) the changes may not be visible to them.
Configure process engine with
Once again, documentation says it clearly:
the process engine is used in a standalone way. Activiti will take care of the transactions.
The configuration is simple:
However, you lose the automatic deployment of processes. This could be mend by borrowing the code from the