cancel
Showing results for 
Search instead for 
Did you mean: 

Transaction will not role back with Annotation @Transaction

larswillrich
Champ in-the-making
Champ in-the-making
Hi,

this my first post and i'm currently working in transaction with spring and activiti Smiley Wink
I have the Problem, that the Transaction will not role back, after there occurs an exception in the function, i witch i start the processinstance. But, if the Exception is in one of the ServicesTasks, the role back willl be successful.

my Processmodel is:
startevent -> ServiceTask -> ServiceTask -> userTask -> ServiceTask -> Endevent

i start the Program by loading a Spring Bean:
        
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:main/TransactionExample-context.xml");
BeanFactory factory = context;
StartSpringExample springExample = (StartSpringExample) factory.getBean("StartSpringExample");
springExample.testingTransaction();

SpringBean:

@Service
public class StartSpringExample {
    // Will be injected by spring
    // Activiti Services and the ProcessEngine
    ProcessEngine processEngine;
    RepositoryService repositoryService;
    RuntimeService runtimeService;

    @Autowired
    public void setProcessEngine(ProcessEngine processEngine) {
        this.processEngine = processEngine;
    }
    @Autowired
    public void setRepositoryService(RepositoryService repositoryService) {
        this.repositoryService = repositoryService;
    }
    @Autowired
    public void setRuntimeService(RuntimeService runtimeService) {
        this.runtimeService = runtimeService;
    }

    public void testingTransaction() {
        try {
            repositoryService
                    .createDeployment()
                    .addInputStream("Transaction.bpmn20.xml",
                            new FileInputStream(new File("src/main/resources/diagrams/Transaction.bpmn20.xml")))
                    .deploy();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return;
        }
        try {
            start(false);
            start(true);
        } catch (Exception e) {
      //Should role back!!
        }
      
      //Only one instance should be exists
    }

    @Transactional
    private void start(boolean b) {
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("employeeName", "testUser");
        // running instance, till arriving the usertask
        ProcessInstance startProcessInstanceByKey = runtimeService.startProcessInstanceByKey("Transaction",variables);
        if (b) throw new UnsupportedOperationException(startProcessInstanceByKey.getId().toString());
    }
}

So, in the function "start" occurs an exception, but the current instance will not role back.
My expected result I have written as a comment in the code.

for further information my TransactionExample-context.xml:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                           http://www.springframework.org/schema/tx      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

  <bean id="dataSource"
    class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
    <property name="driverClass" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
    <property name="username" value="sa" />
    <property name="password" value="" />
  </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="databaseSchemaUpdate" value="true" />
    <property name="jobExecutorActivate" value="false" />
  </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" />

  <tx:annotation-driven transaction-manager="transactionManager" />

  <bean id="StartSpringExample" class="main.StartSpringExample">
    <property name="repositoryService" ref="repositoryService" />
    <property name="runtimeService" ref="runtimeService" />
<property name="processEngine" ref="processEngine" />

  </bean>
</beans>

Thanks in advance.
Lars
4 REPLIES 4

frederikherema1
Star Contributor
Star Contributor

   @Transactional
    private void start(boolean b) {
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("employeeName", "testUser");
        // running instance, till arriving the usertask
        ProcessInstance startProcessInstanceByKey = runtimeService.startProcessInstanceByKey("Transaction",variables);
        if (b) throw new UnsupportedOperationException(startProcessInstanceByKey.getId().toString());
    }

Not sure if private methods with @transactional are "intercepted" by default…

larswillrich
Champ in-the-making
Champ in-the-making
yes… thanks Smiley Wink. that was an error on the one hand, the other is, that the transaction method is not allowed invoke from the same bean. (without AOP)

regards, lars

frederikherema1
Star Contributor
Star Contributor
So did it work out okay, without the private-method?

larswillrich
Champ in-the-making
Champ in-the-making
yes, everthing is fine. The method has to be public.

it is also described therein:

http://stackoverflow.com/questions/4396284/does-spring-transactional-attribute-work-on-a-private-met...

best regards
lars