2016-05-27 58 views
0

我使用Camunda 7.3,Spring 4.2.4和Hibernate 4.3.8,我試圖用與Camunda Documentation中解釋的相同的交易來使用它們。該事務適用於Hibernate操作,但不適用於Camunda操作,如果發生事務回滾而只是恢復了休眠操作。Camunda Spring交易集成不起作用

@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(); 
    } 
} 

dataSource和transactionManager與Spring和Hibernate使用的一樣。

@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"); 
    } 
} 

在執行時會發生回滾上面的代碼和「休眠操作」被rollbacked但在taskService.complete執行的操作都沒有。

我已經調試Camunda代碼,一切似乎都沒問題,我發現了一個SpringTransactionInterceptor,並且這些命令在TransactionTemplate.execute()內執行,此時事務處於活動狀態。

回答

1

在研究了事務Jpa和Spring之後,我發現問題是jpaDialect沒有配置,它負責同步JDBC和JTA事務。

方言對象可以被用於檢索底層的JDBC連接 並且因此允許用於暴露JPA交易作爲JDBC 交易。

我包括下面的代碼到配置,現在它的工作:

@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; 
    } 

    ... 
}