1、引言
Activiti作为一款轻量级、开源的工作流和业务流程管理(BPM)平台,在实际运维过程中,随着业务发展会产生大量需要清理的流程定义,不规范的删除操作可能导致数据不一致或系统异常等问题。本文将介绍Activiti中删除流程定义的相关方式及其适用场景。
2、通过RepositoryService删除流程定义
RepositoryService是Activiti中管理流程定义和部署的核心服务,提供了多种删除流程定义的方法。
2.1、根据部署ID删除
@Service
public class ProcessDefinitionsServiceImpl implements ProcessDefinitionsService {
private final static Logger logger = LoggerFactory.getLogger(ProcessDefinitionsServiceImpl.class);
@Autowired
private RepositoryService repositoryService;
@Override
public AjaxResult deleteProcessByDeploymentId(String deploymentId) {
logger.info("delete start ***!");
repositoryService.deleteDeployment(deploymentId);
logger.info("delete end ***!");
return AjaxResult.success("删除成功!");
}
}
2.1.1、这种方式会删除指定deploymentId的整个部署,包括该部署下的所有流程定义。这是最直接的删除方式,但需要注意以下两点:
①如果该部署下的流程定义已经启动了流程实例,默认会删除失败
②可以通过添加级联参数来删除相关的流程实例
2.1.2、操作涉及表如下所示:
数据表 | 说明 | 执行语句 |
---|
ACT_GE_BYTEARRAY | 存储字节数组数据 | delete from ACT_GE_BYTEARRAY where DEPLOYMENT_ID_ = ? |
ACT_RE_DEPLOYMENT | 存储部署信息 | delete from ACT_RE_DEPLOYMENT where ID_ = ? |
ACT_RU_EVENT_SUBSCR | 存储事件订阅信息 | delete from ACT_RU_EVENT_SUBSCR where PROC_DEF_ID_ = ? and EXECUTION_ID_ is null and PROC_INST_ID_ is null |
ACT_RU_IDENTITYLINK | 存储运行时的用户组、用户和任务之间的关联信息。 | delete from ACT_RU_IDENTITYLINK where PROC_DEF_ID_ = ? |
ACT_RE_PROCDEF | 存储流程定义信息 | delete from ACT_RE_PROCDEF where DEPLOYMENT_ID_ = ? |
2.2、 级联删除部署及实例
@Service
public class ProcessDefinitionsServiceImpl implements ProcessDefinitionsService {
private final static Logger logger = LoggerFactory.getLogger(ProcessDefinitionsServiceImpl.class);
@Autowired
private RepositoryService repositoryService;
@Override
public AjaxResult deleteProcessByDeploymentId(String deploymentId) {
logger.info("delete start ***!");
repositoryService.deleteDeployment(deploymentId, true);
logger.info("delete end ***!");
return AjaxResult.success("删除成功!");
}
}
添加第二个参数为true时,会级联删除该部署相关的所有流程实例、任务和历史数据。适用于需要彻底清理的场景,但生产环境需谨慎使用。
2.3、基础删除方法对比
方法签名 | 级联删除 | 适用场景 |
---|
deleteDeployment(String deploymentId) | × | 没有流程实例的流程定义 |
deleteDeployment(String deploymentId, boolean cascade) | √ | 有流程实例的流程定义 |
3、通过流程定义ID删除
Activiti不直接支持通过流程定义ID删除,因为流程定义属于某个部署。但可以通过以下方式间接实现:
@Service
public class ProcessDefinitionsServiceImpl implements ProcessDefinitionsService {
private final static Logger logger = LoggerFactory.getLogger(ProcessDefinitionsServiceImpl.class);
@Autowired
private RepositoryService repositoryService;
@Override
public AjaxResult deleteProcessByDeploymentId(String processDefinitionId) {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(processDefinitionId)
.singleResult();
repositoryService.deleteDeployment(processDefinition.getDeploymentId(), true);
return AjaxResult.success("删除成功!");
}
}
4、批量删除流程定义
对于需要批量删除的场景,可以通过查询后循环删除:
@Service
public class ProcessDefinitionsServiceImpl implements ProcessDefinitionsService {
private final static Logger logger = LoggerFactory.getLogger(ProcessDefinitionsServiceImpl.class);
@Autowired
private RepositoryService repositoryService;
@Override
public AjaxResult deleteProcessByDeploymentId() {
List<ProcessDefinition> definitions = repositoryService.createProcessDefinitionQuery()
.list();
for (ProcessDefinition pd : definitions) {
repositoryService.deleteDeployment(pd.getDeploymentId(), true);
}
return AjaxResult.success("删除成功!");
}
5、替代删除的方案
在某些场景下,可以考虑以下替代方案而非直接删除:
5.1、挂起流程定义:使其不可启动新实例但不影响现有实例
@Service
public class ProcessDefinitionsServiceImpl implements ProcessDefinitionsService {
private final static Logger logger = LoggerFactory.getLogger(ProcessDefinitionsServiceImpl.class);
@Autowired
private RepositoryService repositoryService;
@Override
public AjaxResult deleteProcessByDeploymentId(String processDefinitionId) {
repositoryService.suspendProcessDefinitionById(processDefinitionId);
return AjaxResult.success();
}
}
5.2、版本控制:部署新版本并停用旧版本