cancel
Showing results for 
Search instead for 
Did you mean: 

Activiti - Spring transactions

subashini
Champ in-the-making
Champ in-the-making
Hi

I am using Activiti with Spring integration. I have configured Activiti and Spring to use transaction manager as given below:

    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="YYYY"/>
    </bean>
   
    <bean id="appsDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="XXXX"/>
    </bean>
   
    <bean id="workflowDbDAO" class="xy.init">   
       <property name="dataSource" ref="appsDataSource" />
    </bean>
   
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <property name="dataSource" ref="dataSource" />
     </bean>
     
    <tx:annotation-driven transaction-manager="transactionManager"/>
   
   <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">      
      <property name="dataSourceJndiName" value="YYYY" />
      <property name="transactionManager" ref="transactionManager" />
       <property name="databaseType" value="oracle" />
       <property name="databaseSchemaUpdate" value="true" />   
       <property name="history" value="audit" />
       <property name="jobExecutorActivate" value="true"/>
       <property name="mailServerUseTLS" value="true" />
   </bean>
   
   <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean" destroy-method="destroy">
     <property name="processEngineConfiguration" ref="processEngineConfiguration" />
  </bean>
 
  <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
  <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
  <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
  <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
  <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
  <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
</beans>

I have a simple workflow as follows:
Start—>Service Task–>Mail Task—> User Task—>End

I have execution Listeners in all of the components. The execution Listeners performs insert/update to a external tables apart from Activiti Schema.

I have an exception thrown @Execution Listener in Service Task. I see that the transaction is handled in the following way:
1. Data in the Activiti Tables has been rolled back. This is as expected as a wait state was not reached. Hence the transaction roll backed.
2. The data changes to external tables have been committed instead of rollback.

I have questions for 2. Shouldn't the external DB and Activiti use the same transaction? If activiti transaction is getting rollbacked, why is the data in the external tables committed, even when an exception is thrown.

Any pointers on this issue will really help me. I am stuck at this point.
5 REPLIES 5

jbarrez
Star Contributor
Star Contributor
"I have questions for 2. Shouldn't the external DB and Activiti use the same transaction?"

Yes, if you have the transaction manager correctly configured.

However your config is missing above. Surround xml snippets with 'code' tags to make them visible.

subashini
Champ in-the-making
Champ in-the-making
Activiti and the external DB were using different transaction manager. My bad. I have fixed it and it is working.

Also I would like to force commit the transaction during my process. My workflow is like this:
Start—-> Mail Task—> Custom DB updates—User Task–> End

I would like to commit after the Mail Task has been sent. Is there any other way to do it other than marking the Mail Task as async:true?

jbarrez
Star Contributor
Star Contributor
No, Activiti flushes only at the end of the transaction (for performance reasons). Making it async is the only way to demarcate transactions.

subashini
Champ in-the-making
Champ in-the-making
I have updated the context file as given below:
<code>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
        xmlns:jee="http://www.springframework.org/schema/jee"
        xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/jee
    http://www.springframework.org/schema/jee/spring-jee.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 
   
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/appDS"/>
    </bean>
   
    <bean id="workflowDbDAO" class="db.WorkflowDbDAOImpl">
     <property name="dataSource" ref="dataSource" />
    </bean>
   
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     <property name="dataSource" ref="dataSource" />
   </bean>
   
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> 
    <property name="dataSource" ref="dataSource" />
    <property name="transactionManager" ref="transactionManager" />
     <property name="databaseType" value="oracle" />
     <property name="databaseSchemaUpdate" value="true" />   
     <property name="history" value="audit" />
     <property name="jobExecutorActivate" value="true"/>
     <property name="mailServerUseTLS" value="true" />
</bean>

<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean" destroy-method="destroy">
   <property name="processEngineConfiguration" ref="processEngineConfiguration" />
  </bean>
 
  <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
  <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
  <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
  <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
  <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
  <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
</beans>
<code>

But still on an error scenario, the custom external tables are geting committed. The activiti tables are not. When they both use the same transaction manager, all the tables should be rolled back.

Any pointers on this issue is highly appreciated.

jbarrez
Star Contributor
Star Contributor
How does your delegate looks like? Is it calling an injected Spring bean that is proxied for transactions?