1、如何理解多租户
- 可以理解为多个应用使用引擎,每个应用直接应该相互隔离互不影响。
- 也可以理解为单个应用有多个组织,每个组织就是一个租户。
多租户可以通过两种不同的方式实现:一种方法是租户与流程引擎一对一;另一种方法是租户与流程引擎多对一。第一种没啥好说的,和平时使用一样,本文主要讲讲第二种。
2、单流程引擎如何应对多租户
所有租户的数据都存储在一个表中(相同的数据库和模式),通过存储在列中的租户标识符(Tenant_id)提供隔离。
在部署流程定义时指定租户id,则说明该定义只属于指定租户,反之则属于所有租户。
使用 Repository Service 创建部署时,可以在DeploymentBuilder上设置租户id 。
Deployment deploy = repositoryService.createDeployment()
.addString("指定租户.bpmn", xml)
.tenantId("001")
.name("指定租户")
.deploy();
查询流程定义时也需要传入租户Id
List<Deployment> deployments = repositoryService
.createDeploymentQuery()
.tenantIdIn("tenant1", "tenant2")
.orderByTenantId()
.asc()
.list();
如果我们在部署时没有使用租户id则意味着所有租户共享,那么在查询时想要查询自己的以及大家共享的
repositoryService.createProcessDefinitionQuery()
.tenantIdIn("someTenantId")
.includeProcessDefinitionsWithoutTenantId()
.list();
成功部署流程定义后,需要考虑的是发起流程实例。正常情况下,我们可以通过流程定义key、流程定义id来发起流程实例,此时不能使用流程定义Key来发起流程实例了,会报如下异常:
我们知道流程定义是有版本的,相同流程定义key部署后版本号叠加,也就是说不同版本的流程定义其流程定义Key是相同的,所以我们发起流程实例时需要使用流程定义id。
我们可以看到在发起流程实例之前有一段代码
List<String> tenantIdList = new ArrayList<>();
tenantIdList.add("001");
identityService.setAuthentication("userOne",null,tenantIdList);
这是设置身份验证信息,否则会报如下异常:
如果处理时觉得使用流程定义Key更方便,可通过以下代码解决
runtimeService
.createProcessInstanceByKey("key")
.processDefinitionTenantId("tenant1")
.execute();
在查询待办任务时也是需要传租户Id的
List<Task> taskList = taskService.createTaskQuery()
.tenantIdIn("001")
.taskAssignee("userOne")
.list();
其他都类似,不一一列举了。