Интеграция транзакций Camunda Spring не работает

Я использую Camunda 7.3, Spring 4.2.4 и Hibernate 4.3.8 и пытаюсь использовать их с той же транзакцией, как описано в Документация Camunda. Транзакция работает нормально с операциями Hibernate, но не с операциями Camunda, если происходит откат транзакции, только операции гибернации возвращаются.

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

При выполнении приведенного выше кода произойдет откат, и «Операции гибернации» откатятся, а операции, выполненные в taskService.complete, — нет.

Я уже отлаживал код Camunda, и все кажется в порядке, я нашел SpringTransactionInterceptor, и команды выполняются внутри TransactionTemplate.execute(), и в этот момент транзакция активна.


person Bruno    schedule 27.05.2016    source источник


Ответы (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;
    }

    ...
}
person Bruno    schedule 14.11.2016
comment
Аннотации @Bean требуются в общих двигателях? - person tmsblgh; 20.03.2021
comment
Та же проблема, но ваше исправление не решает проблему. - person Cristian; 09.04.2021
comment
Можете ли вы включить больше информации о вашей конфигурации? - person Bruno; 28.05.2021