AnsweredAssumed Answered

MultiSchemaMultiTenantProcessEngineConfiguration transaction managment problem

Question asked by blueice on Aug 29, 2017

I am using spring boot with jpa, hibernate and multi tenancy support. You can follow JPA configuration here:

 

 @Bean(destroyMethod = "close")
    public DataSource defaultDataSource() throws PropertyVetoException {
        for (final Tenant tenant : properties.getTenants()) {
            if (tenant.isMasterSchema()) {
                HibernateUtil.setMasterTenant(tenant);
                break;
            }
        }
        final DataSource dataSource = DataSourceProvider.create(ConnectionPoolType.HIKARICP_PRODUCTION, env, HibernateUtil.getMasterTenant());
            return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(final MultiTenantConnectionProvider connectionProvider,
            final CurrentTenantIdentifierResolver tenantResolver) throws Exception {
        final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        final String[] packages = env.getProperty(HibernateConstants.PRO_PACKEGES).split(",");
        em.setPackagesToScan(packages);
        em.setJpaVendorAdapter(vendorAdapter);

        final Properties hibernateProperties = hibernateProperties();
        hibernateProperties.put(org.hibernate.cfg.Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
        hibernateProperties.put(org.hibernate.cfg.Environment.MULTI_TENANT_CONNECTION_PROVIDER, connectionProvider);
        hibernateProperties.put(org.hibernate.cfg.Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, tenantResolver);
        em.setJpaProperties(hibernateProperties);

        DBTypeUtil.setDBType(hibernateProperties());
        return em;
    }


    @Bean
    public MultiTenantConnectionProvider multitenancyConnectionProvider() {
        return new MultiTenantConnectionProviderImpl();
    }

    @Bean
    public CurrentTenantIdentifierResolver tenantResolver(final SessionService service) {
        return new CurrentTenantResolverImpl(service);
    }

    @Bean
    public JPASearchProcessor jpaSearchProcessor() {
        return new JPASearchProcessor(new JPAAnnotationMetadataUtil());
    }

    @Bean
    public PlatformTransactionManager transactionManager(final EntityManagerFactory tenantEntityManager) {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(tenantEntityManager);
        return transactionManager;
    }

 

I am using jpa with activiti same multi tenancy datasources. But I cannot use same TransactionManager together. Activiti config code:

@Bean
    @Conditional(WorkflowActiveCondition.class)
    public ProcessEngine createEngine(final WorkflowTenantInfoHolder tenantInfoHolder, final MsProperties properties,PlatformTransactionManager tm, SessionService service) {
        for (final Tenant tenant : properties.getTenants()) {
            if (!tenant.isEmptySchema()) {
                tenantInfoHolder.addTenant(tenant.getSchemaName());
            }
        }
        final MultiSchemaMultiTenantProcessEngineConfiguration config =
                new MultiSchemaMultiTenantProcessEngineConfiguration(properties,service, tenantInfoHolder);
        config.setDatabaseType(MultiSchemaMultiTenantProcessEngineConfiguration.DATABASE_TYPE_MYSQL);
        config.setDatabaseSchemaUpdate(MultiSchemaMultiTenantProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE);
        config.setAsyncExecutor(new SharedExecutorServiceAsyncExecutor(tenantInfoHolder));

        for (final Tenant tenant : properties.getTenants()) {
            if (!tenant.isEmptySchema()) {
                final DataSource dataSource = datasources.getDataSource(tenant.getSchemaName());
                config.registerTenant(tenant.getSchemaName(), dataSource);
            }
        }
        return config.buildProcessEngine();
    }

 

Example of integration code :

 

    public void save(Basket entity) {
        dao.save(entity);

        // Workflow
        final Map<String, Object> vars = new HashMap<>();
        vars.put("data", entity);
        // Assignee user
        // <userTask id="theTask2" name="my task 2(V2)" activiti:assignee="${person.id}"></userTask>
        vars.put("person", SystemUtil.getActiveUser());

        final RuntimeService runtimeService = workflowService.getRuntimeService();
        runtimeService.startProcessInstanceByKey("oneTaskProcess", entity.getUuid(), vars);
    }

 

 

JPA transaction cannot using from activiti. How can define same transaction(spring) manager for activiti processes?

Outcomes