2016-05-27 55 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; 
    } 

    ... 
}