使用UUID生成器需要添加依赖:
<dependency> <groupId>com.fasterxml.uuid</groupId> <artifactId>java-uuid-generator</artifactId> <version>3.1.3</version> </dependency> 多租户多租户:
通常是在软件需要作为多个不同组织服务时产生的概念
关键是数据分片,组织不能看到其余组织的数据
在这种场景下,组织,部门,小组就叫做租户
多租户和安装多个实例是从基本上不同的:
多租户是一个Activiti流程引擎实例为每个组织分别运行,对应不同的数据表
安装多个Activiti流程引擎实例时,虽然Activiti是轻量级的,运行流程引擎不会消耗很多资源,但是增加了复杂性,并需要更多维护工作.然而对于一些场景,也是正确的解决方案
Activiti的多租户主要围绕着数据分片来实现:
Activiti没有强行校验多租户的规则,即Activiti不会校验查询和使用数据时用户是否使用了正确的租户
校验由Activiti引擎的调用者层负责完成
Activiti只确认租户信息会被保存,并在查询流程数据时会被用到
在向Activiti流程引擎发布流程定义时,需要传递一个租户标识.是一个字符串,限制在256字符内,作为租户的唯一标识
repositoryService.createDeployment() .addClassPathResource(...) .tenantId("myTenantId") .deploy();通过部署传递租户Id有以下作用:
所有包含在部署中的流程定义都会继承部署的tenantId
所有从这些流程定义发起的流程实例,都会继承流程定义的tenantId
所有流程实例运行阶段创建的任务都会继承流程实例的tenantId.单独运行的task也可以包含tenantId
所有流程实例运行阶段创建的分支都会继承流程实例的tenantId
在流程本身或通过API触发一个信号抛出事件可以通过tenantId实现.信号只会在租户环境下执行:如果有多个信号捕获事件,并且名字相同,实际只有正确的tenantId下的事件会被调用
所有作业(定时器,异步调用)会集成tenantId,或者来自流程定义(比如定时开始事件),或流程实例(运行期创建的作业,比如异步调用).这样其实潜在的可以支持为一些租户指定不同优先级的自定义jobExecutor
所有历史实体(历史流程实例,任务和节点)会从对应的运行状态集成tenantId
作为单独的一部分,model也可以设置tenantId.这里的model用来存储Activiti modeler设计的bpmn 2.0模型
为了确保流程数据使用tenantId,所有的查询API都可以通过tenantId进行查询,可以使用其他的实体的对应查询实现替换:
runtimeService.createProcessInstanceQuery() .processInstanceTenantId("myTenantId") .processDefinitionKey("myProcessDefinitionKey") .variableValueEquals("myVar", "someValue") .list()查询API也允许对tenantId使用like语法, 也可以过滤未设置tenantId的实体
重要注意点:
因为数据库的限制,特别是处理null的唯一校验.默认表示未设置租户的tenantId的值是空字符串
流程定义key,流程定义version,tenantId的组合应该是唯一的,这个有数据库约束校验这个规则
要注意tenantId不应设置为null,会影响一些数据库Oracle的查询,会把空字符串当做null处理
这也是为什么withoutTenantId查询会检查空字符串或null.这意味着相同的流程定义,即流程定义key相同可以部署到不同的租户下,可以拥有各自的版本.当不使用租户时也不会影响使用
这些限制不会影响Activiti在集群环境下运行
可以通过调用repositoryService的changeDeploymentTenantId(String deploymentId, String newTenantId) 修改tenantId. 会修改之前继承的所有tenantId. 当需要从非多租户环境向多租户环境下切换时,会非常实用
执行自定义SQLActiviti API允许使用高级API操作数据库:
在查询数据方面,查询API和Native Query API是非常强大的
但是对于某些情况,不够轻便
使用完全自定义的SQL语句:select, insert, update和delete.可以执行在Activiti的数据存储之上,但是完全又可以配置在流程引擎中:比如使用事务
为了使用自定义SQL,Activiti引擎使用MyBatis框架的功能:
因此使用自定义SQL的第一件事,要创建MyBatis映射类