2016-05-27 10 views
0

Ich benutze Camunda 7.3, Spring 4.2.4 und Hibernate 4.3.8 und ich versuche, sie mit der gleichen Transaktion wie in Camunda Documentation erläutert zu verwenden. Die Transaktion funktioniert ordnungsgemäß mit Hibernate-Operationen, nicht jedoch mit Camunda-Operationen. Wenn ein Transaktions-Rollback auftritt, werden nur die Hibernate-Operationen rückgängig gemacht.Camunda Spring Transaction Integration funktioniert nicht

@Configuration 
public class CamundaConfiguration { 

    // Variables with connection Data 

    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
     LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean(); 
     bean.setPersistenceUnitName("PostgreSQL"); 
     bean.setDataSource(dataSource()); 
     bean.getJpaPropertyMap().put("hibernate.dialect", "org.hibernate.dialect.PostgreSQL82Dialect"); 
     bean.getJpaPropertyMap().put("hibernate.ejb.naming_strategy", NamingStrategyLowerCase.class.getCanonicalName()); 
     bean.getJpaPropertyMap().put("hibernate.jdbc.batch_size", 0); 
     bean.getJpaPropertyMap().put("hibernate.cache.use_second_level_cache", true); 
     bean.getJpaPropertyMap().put("hibernate.cache.use_query_cache", true); 
     bean.getJpaPropertyMap().put("javax.persistence.sharedCache.mode", SharedCacheMode.ALL); 
     bean.getJpaPropertyMap().put("hibernate.cache.default_cache_concurrency_strategy", "read-write"); 
     bean.getJpaPropertyMap().put("javax.persistence.validation.factory", validator); 
     bean.getJpaPropertyMap().put("hibernate.cache.region.factory_class", SingletonEhCacheRegionFactory.class.getCanonicalName()); 
     bean.setPersistenceProviderClass(org.hibernate.jpa.HibernatePersistenceProvider.class); 
     bean.setPackagesToScan("br.com.model"); 
     return bean; 
    } 

    @Bean 
    public JpaTransactionManager transactionManager() { 
     JpaTransactionManager bean = new JpaTransactionManager(entityManagerFactory()); 
     bean.getJpaPropertyMap().put("org.hibernate.flushMode", FlushMode.AUTO); 
     bean.setDataSource(dataSource); 
     bean.setPersistenceUnitName("PostgreSQL"); 
     return bean; 
    } 

    @Bean 
    public DataSource dataSource() { 
     HikariConfig config = new HikariConfig(); 
     config.setDriverClassName(driverClass); 
     config.setJdbcUrl(jdbcUrl); 
     config.setUsername(username); 
     config.setPassword(password); 
     config.setMaximumPoolSize(50); 
     config.setConnectionTestQuery("select 1"); 

     HikariDataSource bean = new HikariDataSource(config); 
     return new LazyConnectionDataSourceProxy(bean); 
    } 

    @Bean 
    public ManagedProcessEngineFactoryBean processEngine() { 
     ManagedProcessEngineFactoryBean processEngineFactoryBean = new ManagedProcessEngineFactoryBean(); 
     processEngineFactoryBean.setProcessEngineConfiguration(processEngineConfiguration()); 
     return processEngineFactoryBean; 
    } 

    @Bean 
    public SpringProcessEngineConfiguration processEngineConfiguration() { 
     SpringProcessEngineConfiguration processEngineConfiguration = new SpringProcessEngineConfiguration(); 
     processEngineConfiguration.setDataSource(dataSource()); 
     processEngineConfiguration.setTransactionManager(transactionManager()); 
     processEngineConfiguration.setJobExecutorActivate(true); 
     processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_TRUE); 
     return processEngineConfiguration; 
    } 

    @Bean 
    public TaskService taskService() throws Exception { 
     return processEngine().getObject().getTaskService(); 
    } 
} 

die Datenquelle und transaction ist das gleiche von Spring und Hibernate verwendet.

@Service 
public class TaskManager { 
    @Inject 
    private TaskService taskService; 

    @Transactional 
    public void completeTask(String taskId, final Map<String, Object> variables) { 

     org.camunda.bpm.engine.task.Task camundaTask = taskService.createTaskQuery().taskId(taskId).singleResult(); 
     taskService.complete(camundaTask.getId(), variables); 

     // Hibernate Operations 

     throw new RuntimeException("Exception test"); 
    } 
} 

Bei der Ausführung der Code über einem Rollbacks auftreten und die ‚Hibernate Operationen‘ sind rollbacked aber die in taskService.complete ausgeführten Operationen sind es nicht.

Ich bereits debugged der Camunda-Code und alles scheint in Ordnung, ich fand einen SpringTransactionInterceptor und die Befehle werden innerhalb einer TransactionTemplate.execute() ausgeführt und zu diesem Zeitpunkt ist die Transaktion aktiv.

Antwort

1

Nach dem Studium über Transaktionen, Jpa und Spring, fand ich das Problem, dass jpaDialect nicht konfiguriert ist, ist es verantwortlich, JDBC und JTA-Transaktionen zu synchronisieren.

Das Dialekt-Objekt kann die darunter liegende JDBC Verbindung und ermöglicht somit für die Belichtung JPA-Transaktionen als Transaktionen JDBC abzurufen verwendet werden.

I enthalten den folgenden Code in die Konfiguration und jetzt ist es funktioniert:

@Configuration 
public class CamundaConfiguration { 
    .... 

    @Bean 
    public JpaDialect jpaDialect() { 
     return new org.springframework.orm.jpa.vendor.HibernateJpaDialect(); 
    } 

    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
     LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean(); 
     bean.setJpaDialect(jpaDialect()); 
     bean.setJpaVendorAdapter(new org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter()); 
     ... 
     return bean; 
    } 

    @Bean 
    public JpaTransactionManager transactionManager() { 
     JpaTransactionManager bean = new JpaTransactionManager(entityManagerFactory()); 
     bean.setJpaDialect(jpaDialect()); 
     ... 
     return bean; 
    } 

    ... 
}