cancel
Showing results for 
Search instead for 
Did you mean: 

Configuring transaction manager for activiti process engine.

susubhas
Champ in-the-making
Champ in-the-making
Hi,

In my application i have transactionManager already defined which is either JTA or Hibernate transaction manager depending on which server the app will be deployed on. I have configured SpringProcessEngineConfiguration to use this transactionManager, but activiti doesn't reuse existing transaction instead it creates new one for every action. For example if i am performing some action on my app in a transaction and as part of this action if there is some update to activiti engine, activiti is not using the existing transation, i am saying this because if the main action fails for some reason then even the activiti related update should be rolled back which i dont see happening.


Rgds,
Sujata
13 REPLIES 13

jbarrez
Star Contributor
Star Contributor
What does your activiti config look like? Without it, we can only guess.

susubhas
Champ in-the-making
Champ in-the-making
Hi jbarrez,

Spring activiti config file is pasted below. Here "txManager" is the HibernateTransactionManager which is created on the datasource looked up below.


<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">

    <import resource="Spring.core.beans.xml"/>
    <bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <property name="targetDataSource">
            <jee:jndi-lookup id="dbDataSource"
                jndi-name="@jndi-name@"
                />
        </property>
    </bean>

    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
        <property name="databaseType" value="@db-type@" />
        <property name="dataSource" ref="dataSource"/>
        <property name="transactionManager" ref="txManager" />
        <property name="databaseSchemaUpdate" value="false" />
        <property name="historyLevel"  value="ACTIVITY"/>
        <property name="preParseListeners">
            <list>
                <bean class="com.dev.sdp.core.workflow.listeners.SDPBpmnParseListener"/>
            </list>
        </property>
    </bean>

    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <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" />
</beans>



Rgds,
Sujata

araghuraman
Champ in-the-making
Champ in-the-making
Perhaps a new transaction is required because it does not want you to tie your business logic (short transaction)
with its own transaction (long transaction). If you want to execute the workflow process in a transactional way, have you tried using transaction sub process with compensation handlers?

susubhas
Champ in-the-making
Champ in-the-making
It not during process runtime, its during process deploying. I am trying to deploy multiple process definitions(not using .Bar purposely because i want a deploymentId for each processDefinition), in one call and i am expecting if the deployment of one process definition fails also all the other deployments should rollback which is not happening now.

Rgds,
Sujata

susubhas
Champ in-the-making
Champ in-the-making
Any Solution for the above issue???

jbarrez
Star Contributor
Star Contributor
I am trying to deploy multiple process definitions

How are you doing that? In a method marked with @Transactional?

susubhas
Champ in-the-making
Champ in-the-making
Yes, my method looks like below

@Transactional   
public void registerOrUpdateWorkflowDefinition(String barFileUrl)
            throws InvalidArgumentException, WorkflowServiceException
    {
        LOGGER.info("barFileUrl" + barFileUrl);
        Deployment deployment;
        List<String> keys = null;
        try
        {
            if (StringUtil.isEmpty(barFileUrl))
            {
                LOGGER.error("barFileUrlis null or empty");
                throw new InvalidArgumentException(WorkflowServiceErrorCode.ERROR_020001);
            }

            ZipInputStream zipInputStream = new ZipInputStream(new   FileInputStream(SharedFSUtil.getLocalFilePath(barFileUrl)));
            ZipEntry entry = zipInputStream.getNextEntry();
            byte[] buffer = new byte[1024];

            while(entry!=null){
                String newFileName = entry.getName();
                File newFile = new File(newFileName);
                FileOutputStream fos = new FileOutputStream(newFile);
                int len;
                while ((len = zipInputStream.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                fos.close();

                repositoryService.createDeployment().addInputStream(newFileName,new FileInputStream(newFile)).deploy();

                entry = zipInputStream.getNextEntry();
            }

        }
        catch (FileNotFoundException fnfExe)
        {
            LOGGER.error("Could not find file at the specified shared location " + fnfExe);
            throw new InvalidArgumentException(WorkflowServiceErrorCode.ERROR_020002);
        }
        catch (ActivitiException aExe)
        {
            LOGGER.error("Unknown error occured during workflow registration " + aExe);
            throw new WorkflowServiceException(aExe.getMessage());
        } catch (IOException e) {
            e.printStackTrace(); 
        }
    }

jbarrez
Star Contributor
Star Contributor
It looks all ok.

I tried a simple test that mimics your use case but I couldn't make it fail: see https://github.com/Activiti/Activiti/commit/c4e454c93f0fbf0d74b47e141f808d62682a9d33

susubhas
Champ in-the-making
Champ in-the-making
But in my app i have hibernate, so i am creating HibernateTransactionManager by passing sessionFactory to it. And to activiti i m passing the reference of this transaction manager. I guess activiti creates its own sessionFactory. is it that the transaction manager is only managing the transaction for the sessions which it knows about???

Rgds,
Sujata