activiti5更新流程定义,清除流程定义缓存

1. activiti5使用command命令清除流程定义缓存
package com.yl.command;

import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.deploy.DeploymentCache;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.apache.commons.lang3.StringUtils;

import java.util.Objects;

/**
 * 清除缓存
 *
 * @author liuxb
 * @date 2022/12/11 12:36
 */
@Slf4j
public class ClearProcDefCacheCmd implements Command<Object> {
    /**
     * procDefId 流程定义id
     */
    private String procDefId;

    public ClearProcDefCacheCmd(String procDefId) {
        this.procDefId = procDefId;
    }


    @Override
    public Object execute(CommandContext commandContext) {
        try {
            //清除缓存
            DeploymentCache<ProcessDefinitionEntity> processDefinitionCache = commandContext.getProcessEngineConfiguration().getProcessDefinitionCache();
            if (StringUtils.isNoneBlank(procDefId)) {
                ProcessDefinitionEntity processDefinitionEntity = processDefinitionCache.get(procDefId);
                if (Objects.nonNull(processDefinitionEntity)) {
                    processDefinitionCache.remove(procDefId);
                    log.info("-------------清除deployId:{}, procDefId:{}, 流程定义缓存--------------", processDefinitionEntity.getDeploymentId(), procDefId);
                }
            } else {
                processDefinitionCache.clear();
                log.info("-------------清除全部流程定义缓存--------------");
            }
        } catch (Exception e) {
            log.error("删除流程定义缓存异常", e);
        }

        return null;
    }
}

执行command命令

  @Autowired
    private ManagementService managementService;

    /**
     * 清除流程定义缓存
     *
     * @param procDefId 流程定义id
     */
    public void executeClearProcDefCacheCmd(String procDefId) {
        managementService.executeCommand(new ClearProcDefCacheCmd(procDefId));
    }

注意需要读取activiti的表act_ge_bytearray

2. activiti5使用command命令更新流程定义并清除流程定义缓存

UpdateByteArrayCmd

package com.yl.command;

import com.yl.exception.FlowException;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ByteArrayEntity;

/**
 * 修改流程定义表act_ge_bytearray,并清除缓存
 *
 * @author liuxb
 * @date 2022/12/11 12:36
 */
@Slf4j
public class UpdateByteArrayCmd implements Command<Object> {
    /**
     * act_ge_bytearray表实体类
     */
    private ByteArrayEntity byteArrayEntity;
    /**
     * procDefId 流程定义id
     */
    private String procDefId;

    public UpdateByteArrayCmd(ByteArrayEntity byteArrayEntity, String procDefId) {
        this.byteArrayEntity = byteArrayEntity;
        this.procDefId = procDefId;
    }


    @Override
    public Object execute(CommandContext commandContext) {
        try {
            //org.activiti.engine.ActivitiOptimisticLockingException: ByteArrayEntity[id=2, name=null, size=4479] was updated by another transaction concurrently
            //更新act_ge_bytearray表,使用了乐观锁,必须加上版本号
            commandContext.getDbSqlSession().update(byteArrayEntity);
            //清除缓存
            commandContext.getProcessEngineConfiguration().getProcessDefinitionCache().remove(procDefId);
            log.info("-------------更新流程定义并删除缓存deployId:{}, ,procDefId:{}--------------", byteArrayEntity.getDeploymentId(), procDefId);
        } catch (Exception e) {
            throw new FlowException("更新流程定义文件异常", e);
        }

        return null;
    }
}

CommandUtil

package com.yl.util;

import com.yl.command.ClearProcDefCacheCmd;
import com.yl.command.UpdateByteArrayCmd;
import org.activiti.engine.ManagementService;
import org.activiti.engine.impl.persistence.entity.ByteArrayEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 执行command服务
 *
 * @author liuxb
 * @date 2022/12/11 17:53
 */
@Service
public class CommandUtil {
    @Autowired
    private ManagementService managementService;

    /**
     * 修改流程定义并清除缓存
     *
     * @param byteArrayEntity
     * @param procDefId 流程定义id
     */
    public void executeUpdateByteArrayCmd(ByteArrayEntity byteArrayEntity, String procDefId) {
        managementService.executeCommand(new UpdateByteArrayCmd(byteArrayEntity, procDefId));
    }

    /**
     * 清除流程定义缓存
     *
     * @param procDefId 流程定义id
     */
    public void executeClearProcDefCacheCmd(String procDefId) {
        managementService.executeCommand(new ClearProcDefCacheCmd(procDefId));
    }

}

GeByteArrayService

package com.yl.service;

import com.yl.entity.GeByteArrayEntity;
import com.yl.exception.FlowException;
import com.yl.mapper.GeByteArrayMapper;
import com.yl.util.CommandUtil;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.impl.persistence.entity.ByteArrayEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * 对应 act_ge_bytearray表的实体类
 *
 * @author liuxubo
 * @date 2022/11/20 17:14
 */
@Slf4j
@Service
public class GeByteArrayService {
    @Autowired
    private GeByteArrayMapper geByteArrayMapper;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private CommandUtil commandUtil;

    /**
     * 修改流程定义并清除缓存
     *
     * @param multipartFile      修改后的流程定义文件
     * @param procDefId          要修改的流程定义id
     * @return
     */
    public int update(MultipartFile multipartFile, String procDefId) {
        if (multipartFile == null || multipartFile.isEmpty()) {
            throw new FlowException("上传流程定义文件不能为空");
        }
        if (StringUtils.isBlank(procDefId)) {
            throw new FlowException("流程定义id不能为空");
        }

        GeByteArrayEntity geByteArrayEntity = getGeByteArrayEntity(procDefId);

        try {
            byte[] bytes = multipartFile.getBytes();

            ByteArrayEntity byteArrayEntity = new ByteArrayEntity(bytes);
            byteArrayEntity.setId(geByteArrayEntity.getId());
            //版本号不能为空,有乐观锁
            byteArrayEntity.setRevision(geByteArrayEntity.getVer());
            byteArrayEntity.setName(geByteArrayEntity.getName());
            byteArrayEntity.setDeploymentId(geByteArrayEntity.getDeploymentId());
            commandUtil.executeUpdateByteArrayCmd(byteArrayEntity, procDefId);
        } catch (Exception e) {
            throw new FlowException("更新流程定义异常", e);
        }

        return Objects.nonNull(geByteArrayEntity) ? 1 : 0;
    }

    /**
     * 清除流程定义缓存
     *
     * @param procDefId 要修改的流程定义id
     * @return
     */
    public boolean clearCache(String procDefId) {
//        String id = "";
//        if(StringUtils.isNoneBlank(procDefId)){
//            GeByteArrayEntity geByteArrayEntity = getGeByteArrayEntity(procDefId);
//            id = geByteArrayEntity.getId();
//        }

        commandUtil.executeClearProcDefCacheCmd(procDefId);
        return true;
    }

    /**
     * 根据流程定义id查询流程定义的二进制数据
     *
     * @param procDefId 要修改的流程定义id
     * @return
     */
    private GeByteArrayEntity getGeByteArrayEntity(String procDefId) {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
                processDefinitionId(procDefId)
                .singleResult();
        if (Objects.isNull(processDefinition)) {
            throw new FlowException("流程定义文件查询不存在");
        }

        String deploymentId = processDefinition.getDeploymentId();
        String bpmnName = "";
        List<String> resourceNames = repositoryService.getDeploymentResourceNames(deploymentId);
        for (String resourceName : resourceNames) {
            if (resourceName.endsWith(".bpmn") || resourceName.endsWith(".xml")) {
                bpmnName = resourceName;
                break;
            }
        }

        GeByteArrayEntity geByteArrayEntity = geByteArrayMapper.findByDeploymentId(deploymentId, bpmnName);
        log.info("id:{}, ver:{}, name:{}, deploymentId:{}", geByteArrayEntity.getId(), geByteArrayEntity.getVer(), geByteArrayEntity.getName(), geByteArrayEntity.getDeploymentId());
        return geByteArrayEntity;
    }

}

GeByteArrayEntity

package com.yl.entity;

import lombok.Data;

/**
 * 对应 act_ge_bytearray表的实体类
 *
 * @author liuxubo
 * @date 2022/11/20 17:14
 */
@Data
public class GeByteArrayEntity {
    /**
     * 主键id
     */
    private String id;
    /**
     * 版本
     */
    private Integer ver;
    /**
     * 部署文件名
     */
    private String name;
    /**
     * 部署文件的二进制数据
     */
    private byte[] bytes;
    /**
     * 部署id
     */
    private String deploymentId;
    /**
     * 该资源是否是activiti引擎自动生成(0表示用户生成,1表示由activiti引擎生成)
     */
    private boolean generated = false;
}

GeByteArrayMapper

package com.yl.mapper;

import com.yl.entity.GeByteArrayEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 对应 act_ge_bytearray表的实体类
 *
 * @author liuxubo
 * @date 2022/11/20 17:14
 */
@Mapper
public interface GeByteArrayMapper {
    List<GeByteArrayEntity> findList(GeByteArrayEntity geByteArrayEntity);

    GeByteArrayEntity findByDeploymentId(@Param("deploymentId") String deploymentId, @Param("name") String name);

    int add(GeByteArrayEntity geByteArrayEntity);

    int deleteByDeploymentId(@Param("deploymentId") String deploymentId, @Param("name") String name);

    int update(GeByteArrayEntity geByteArrayEntity);
}

GeByteArrayMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace='com.yl.mapper.GeByteArrayMapper'>

    <resultMap id='applyDataResultMap' type='com.yl.entity.GeByteArrayEntity'>
        <id column='ID_' property='id' jdbcType='VARCHAR' />
        <result column='REV_' property='ver' jdbcType='INTEGER' />
        <result column='NAME_' property='name' jdbcType='VARCHAR' />
        <result column='BYTES_' property='bytes' jdbcType='BLOB' />
        <result column='DEPLOYMENT_ID_' property='deploymentId' jdbcType='VARCHAR' />
        <result column='GENERATED_' property='generated' jdbcType='BOOLEAN' />
    </resultMap>

    <sql id='applyDataColumns'>
        ID_,REV_,NAME_,BYTES_,DEPLOYMENT_ID_,GENERATED_
    </sql>

    <select id='findList' resultMap='applyDataResultMap'>
        SELECT
        <include refid='applyDataColumns'/>
        FROM act_ge_bytearray
        <where>
            <if test='id != null and id != "" '> and ID_=#{id}</if>
            <if test='REV_ != null '> and REV_=#{rev}</if>
            <if test='name != null and name != "" '> and NAME_=#{name}</if>
            <if test='deploymentId != null and deploymentId != "" '> and DEPLOYMENT_ID_=#{deploymentId}</if>
        </where>
    </select>

    <select id='findByDeploymentId' resultMap='applyDataResultMap'>
        SELECT
        <include refid='applyDataColumns'/>
        FROM act_ge_bytearray
        WHERE DEPLOYMENT_ID_=#{deploymentId} and NAME_=#{name}
    </select>

    <insert id='add'>
        INSERT INTO act_ge_bytearray(
            ID_,REV_,NAME_,BYTES_,DEPLOYMENT_ID_,GENERATED_
        )
        VALUES (
                   #{id},1, #{name},#{bytes},#{deploymentId},0
               )
    </insert>

    <delete id='deleteByDeploymentId'>
        DELETE FROM act_ge_bytearray WHERE DEPLOYMENT_ID_=#{deploymentId} and NAME_=#{name}
    </delete>

    <!-- 只修改流程部署文件内容 -->
    <update id='update'>
        UPDATE act_ge_bytearray
        <set>
            <if test='bytes != null '>BYTES_=#{bytes}</if>
        </set>
        WHERE DEPLOYMENT_ID_=#{deploymentId} and NAME_=#{name}
    </update>

</mapper>

GeByteArrayController

package com.yl.controller;

import com.yl.common.annotation.RequestSingleBody;
import com.yl.common.base.RetModel;
import com.yl.common.base.RetResult;
import com.yl.common.base.vo.FlagVo;
import com.yl.common.base.vo.NumberVo;
import com.yl.common.base.vo.ViewObject;
import com.yl.service.GeByteArrayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * 流程定义
 *
 * @author liuxb
 * @date 2022/11/20 18:07
 */
@Validated
@RestController
@RequestMapping("/activiti5/geByteArray")
public class GeByteArrayController {
    @Autowired
    private GeByteArrayService geByteArrayService;


    /**
     * 修改流程定义
     *
     * @param file      修改后的流程定义文件
     * @param procDefId 要修改的流程定义id
     * @return
     */
    @PostMapping("/update")
    public RetResult<NumberVo> update(MultipartFile file, String procDefId) {
        return RetModel.ok().setData(ViewObject.number(geByteArrayService.update(file, procDefId)));
    }


    /**
     * 清除流程定义缓存
     *
     * @param procDefId 要修改的流程定义id
     * @return
     */
    @PostMapping("/clearCache")
    public RetResult<FlagVo> clearCache(@RequestSingleBody String procDefId) {
        return RetModel.ok().setData(ViewObject.flag(geByteArrayService.clearCache(procDefId)));
    }
}
3. 总结
//更新act_ge_bytearray表,使用了乐观锁,必须加上版本号,否则报错 org.activiti.engine.ActivitiOptimisticLockingException
  commandContext.getDbSqlSession().update(byteArrayEntity);
  
 //如果是activit6,只需修改ClearProcDefCacheCmd内
  DeploymentCache<ProcessDefinitionCacheEntry> processDefinitionCache = commandContext.getProcessEngineConfiguration().getProcessDefinitionCache(); 

注意:修改完流程定义后,如果不清除缓存,会不生效,或者不清除缓存,重启项目也可以     
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值