Camunda Spring 事务集成不工作
Camunda Spring Transaction Integration not working
我正在使用 Camunda 7.3、Spring 4.2.4 和 Hibernate 4.3.8,我正在尝试将它们与 Camunda Documentation 中解释的相同事务一起使用。该事务可以与 Hibernate 操作一起使用,但不能与 Camunda 操作一起使用,如果发生事务回滚,则仅恢复 hibernate 操作。
@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");
}
}
上面的代码执行时会发生回滚,'Hibernate Operations' 会回滚,但 taskService.complete 中执行的操作不会。
我已经调试了 Camunda 代码并且一切正常,我找到了一个 SpringTransactionInterceptor 并且命令在 TransactionTemplate.execute()
中执行,此时事务处于活动状态。
在研究了事务、Jpa 和 Spring 之后,我发现问题是没有配置 jpaDialect,它负责同步 JDBC 和 JTA 事务。
The dialect object can be used to retrieve the underlying JDBC
connection and thus allows for exposing JPA transactions as JDBC
transactions.
我将以下代码包含到配置中,现在可以正常工作了:
@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;
}
...
}
我正在使用 Camunda 7.3、Spring 4.2.4 和 Hibernate 4.3.8,我正在尝试将它们与 Camunda Documentation 中解释的相同事务一起使用。该事务可以与 Hibernate 操作一起使用,但不能与 Camunda 操作一起使用,如果发生事务回滚,则仅恢复 hibernate 操作。
@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");
}
}
上面的代码执行时会发生回滚,'Hibernate Operations' 会回滚,但 taskService.complete 中执行的操作不会。
我已经调试了 Camunda 代码并且一切正常,我找到了一个 SpringTransactionInterceptor 并且命令在 TransactionTemplate.execute()
中执行,此时事务处于活动状态。
在研究了事务、Jpa 和 Spring 之后,我发现问题是没有配置 jpaDialect,它负责同步 JDBC 和 JTA 事务。
The dialect object can be used to retrieve the underlying JDBC connection and thus allows for exposing JPA transactions as JDBC transactions.
我将以下代码包含到配置中,现在可以正常工作了:
@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;
}
...
}