cancel
Showing results for 
Search instead for 
Did you mean: 

Update custom tables along with Activiti Tables

subashini
Champ in-the-making
Champ in-the-making
We are updating custom table using listener in the user task, service task and Email task , as part of our workflow. We are using the same transaction manager for both Activiti and the Custom tables. But even then, when there is a error in the listener, Activiti is not getting committed, but the local tables are committed with partial data.

Activiti Version : 5.15.1
Weblogic: 12.2.1

This is our activiti-config.xml
<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>

Any pointers is highly appreciated. It is causing lot of confusion, when a error occurs.
7 REPLIES 7

hari
Star Contributor
Star Contributor
I would prefer going for a service task if there are chances of exception in task listeners.

subashini
Champ in-the-making
Champ in-the-making
The same behavior is seen for service task.

jbarrez
Star Contributor
Star Contributor
Can you post your delegate? Is it a Spring bean? Are the other services injected into it?
A process xml would also help.

subashini
Champ in-the-making
Champ in-the-making
This is my execution listener.
public class TMCWFNotificationListener implements ExecutionListener {
private Expression assignedTo;
private Expression message;
private Expression ds;

Logger logger =  LoggerFactory.getLogger(TMCWFNotificationListener.class);
@Override
public void notify(DelegateExecution arg0) throws Exception{
  // TODO Auto-generated method stub
  int entityId = 0;
  String assignee = "",messageval = "";
 
  NotificationObject notifyObj = new NotificationObject(); 
  WorkflowDbDAOImpl jdbcDAO = (WorkflowDbDAOImpl) ds.getValue(arg0);
 
  String entityIdString = (String) arg0.getVariable("EntityId");

  notifyObj.setEntitytype(entityType);
  notifyObj.setEntityid(entityId);
  notifyObj.setAssignedto(assignee);
  notifyObj.setMessage(messageval);
 
  logger.info("Inside notification Listener");
 
  jdbcDAO.insertNotifications(notifyObj);   
}

}

I am injecting the values to this is listener from my Process.

ds - ${workflowDbDAO}
assignedTo ${reminderobj.email}
message - Reminder - ${stepMessage} Notification

davanna
Champ in-the-making
Champ in-the-making
I had similar questions. In my case, I was using Spring boot application. I was using a transactionManager auto injected with my data source pointing to my tables. The transaction manager is a JPATransactionManager implementation. I was updating the tables in the event listeners. The same transaction manager along with a datasource pointing to activiti tables was passed to initialize the SpringProcessEngineConfiguration. The behavior is proper and working fine. The activiti engine underneath it uses Mybatis and uses the datasource passed to it accordingly. But my question is that how we can use the same transaction manager for two different data sources. The Spring documentation says that JpaTransactionManager must be used with one datasource. I have asked this question here - https://forums.activiti.org/content/multiple-data-sources-activiti

In your case, you are using the same datsource for both the updates i.e. your tables as well as activiti. Basically you have defined your tables in the same schema as the activiti. In my case, I have defined the tables in different schemas respectively for activiti and my tables.

subashini
Champ in-the-making
Champ in-the-making
Thank you for sharing your use case. I am using just a single datasource, but still the transactions are getting committed seperately. Initially, we used seperate data source. Then I modified to use the same datasource, but still it is not working.

How did you inject the transaction manager to the event listeners?

jbarrez
Star Contributor
Star Contributor
Your TMCWFNotificationListener needs to be a spring bean too … or it won't participate in the same transaction. You need to reference it in your process via an expression. And then you can simply @AutoWired your dependencies like the DAO class you're using.