记一次借助Eclipse MAT排查OOM

记一次借助Eclipse MAT排查OOM

近日,在我们的生产应用集群发生了一起因用户操作顺序不合适导致的OOM事件,引发了领导阶级的重点关注!!!特记录排查过程

Zabbix监控

此处不放图了,通过观看Zabbix对中间件的JMX监控,可以看到老生代有频繁的GC,与往日有很大区别,CPU负载跑满了8C,显然是发生了Full GC。

宝蓝德实例堆内存配置

我们使用的war包部署模式,中间件没有使用常规的Tomcat,而是使用了宝蓝德BES952。

在8C16T的虚拟机上,配置了Xms和Xmx为2GB,元空间为512MB。配置的属实有点小。。。

宝蓝德Dump配置

由于已经开启了:

-XX: +HeapDumpOnOutOfMemoryError

-XX: HeapDumpPath

所以在发生老生代Full GC时,会自动Dump出堆内存。

MAT导入Dump

可以看到有个灰常庞大的对象,导致了引用达到了1.3GB。

大对象的调用堆栈

这种情况显然是发生了扫全表。

经过排查发现,报错的位置涉及对Activiti流程引擎历史表的查询操作:

java 复制代码
List<HistoricTaskInstance> list = historyService.createTaskInstanceQuery().processInstanceId("这里是一个String格式的实例id").list();

翻看Activiti流程引擎源码

Java

java 复制代码
D:\mavenData\org\activiti\activiti-engine\7.1.0.M6\activiti-engine-7.1.0.M6.jar!\org\activiti\engine\impl\HistoricTaskInstanceQueryImpl.class
    public HistoricTaskInstanceQueryImpl processInstanceId(String processInstanceId) {
        if (this.inOrStatement) {
            this.currentOrQueryObject.processInstanceId = processInstanceId;
        } else {
            this.processInstanceId = processInstanceId;
        }

        return this;
    }

对应的Mybatis的Mapper

xml 复制代码
D:\mavenData\org\activiti\activiti-engine\7.1.0.M6\activiti-engine-7.1.0.M6.jar!\org\activiti\db\mapping\entity\HistoricTaskInstance.xml

<sql id="commonSelectHistoricTaskInstancesByQueryCriteriaSql">
    <if test="candidateUser != null || candidateGroups != null || involvedGroups != null">
      inner join ${prefix}ACT_HI_IDENTITYLINK HI on HI.TASK_ID_ = RES.ID_
    </if>
    <if test="processFinished || processUnfinished || processInstanceBusinessKey != null || processInstanceBusinessKeyLike != null || processInstanceBusinessKeyLikeIgnoreCase != null">
      inner join ${prefix}ACT_HI_PROCINST HPI ON RES.PROC_INST_ID_ = HPI.ID_
    </if>
    <if test="processDefinitionKey != null || processDefinitionKeyLike != null || processDefinitionKeyLikeIgnoreCase != null || processDefinitionName != null || processDefinitionNameLike != null || (processCategoryInList != null &amp;&amp; processCategoryInList.size() &gt; 0) || (processCategoryNotInList != null &amp;&amp; processCategoryNotInList.size() &gt; 0) || (processDefinitionKeys != null &amp;&amp; processDefinitionKeys.size() &gt; 0)">
      inner join ${prefix}ACT_RE_PROCDEF D on RES.PROC_DEF_ID_ = D.ID_
    </if>
    <if test="deploymentId != null || (deploymentIds != null &amp;&amp; deploymentIds.size() &gt; 0)">
      left outer join ${prefix}ACT_RE_PROCDEF DEPLOY_P ON RES.PROC_DEF_ID_ = DEPLOY_P.ID_
    </if>
    <foreach collection="queryVariableValues" index="index" item="var">
      <choose>
        <when test="var.local">
          inner join ${prefix}ACT_HI_VARINST A${index} on RES.ID_ = A${index}.TASK_ID_ 
        </when>
        <otherwise>
          inner join ${prefix}ACT_HI_VARINST A${index} on RES.PROC_INST_ID_ = A${index}.PROC_INST_ID_ 
        </otherwise>
      </choose>       
    </foreach>
    <foreach collection="orQueryObjects" index="orIndex" item="orQueryObject">
      <if test="orQueryObject.candidateUser != null || orQueryObject.candidateGroups != null || orQueryObject.involvedGroups != null">
        <choose>
          <when test="orQueryObject.involvedGroups != null">left</when>
          <otherwise>inner</otherwise>
        </choose>
         join ${prefix}ACT_HI_IDENTITYLINK HI_OR${orIndex} on HI_OR${orIndex}.TASK_ID_ = RES.ID_
      </if>
      <if test="orQueryObject.processFinished || orQueryObject.processUnfinished || orQueryObject.processInstanceBusinessKey != null || orQueryObject.processInstanceBusinessKeyLike != null || orQueryObject.processInstanceBusinessKeyLikeIgnoreCase != null">
        inner join ${prefix}ACT_HI_PROCINST HPI_OR${orIndex} ON RES.PROC_INST_ID_ = HPI_OR${orIndex}.ID_
      </if>
      <if test="orQueryObject.processDefinitionKey != null || orQueryObject.processDefinitionKeyLike != null || orQueryObject.processDefinitionKeyLikeIgnoreCase != null || orQueryObject.processDefinitionName != null || orQueryObject.processDefinitionNameLike != null || (orQueryObject.processCategoryInList != null &amp;&amp; orQueryObject.processCategoryInList.size() &gt; 0) || (orQueryObject.processCategoryNotInList != null &amp;&amp; orQueryObject.processCategoryNotInList.size() &gt; 0) || (orQueryObject.processDefinitionKeys != null &amp;&amp; orQueryObject.processDefinitionKeys.size() &gt; 0)">
        left outer join ${prefix}ACT_RE_PROCDEF D_OR${orIndex} on RES.PROC_DEF_ID_ = D_OR${orIndex}.ID_
      </if>
      <if test="orQueryObject.deploymentId != null || (orQueryObject.deploymentIds != null &amp;&amp; orQueryObject.deploymentIds.size() &gt; 0)">
        left outer join ${prefix}ACT_RE_PROCDEF DEPLOY_P_OR${orIndex} ON RES.PROC_DEF_ID_ = DEPLOY_P_OR${orIndex}.ID_
      </if>
      <if test="orQueryObject.queryVariableValues.size() &gt; 0">
        <if test="orQueryObject.hasLocalQueryVariableValue()">
          left outer join ${prefix}ACT_HI_VARINST A_L_OR${orIndex} on RES.ID_ = A_L_OR${orIndex}.TASK_ID_ 
        </if>
        <if test="orQueryObject.hasNonLocalQueryVariableValue()">
          left outer join ${prefix}ACT_HI_VARINST A_OR${orIndex} on RES.PROC_INST_ID_ = A_OR${orIndex}.PROC_INST_ID_ 
        </if>
      </if>
    </foreach>
    <where>
      <if test="taskId != null">
        RES.ID_ = #{taskId}
      </if>
      <if test="processDefinitionId != null">
        and RES.PROC_DEF_ID_ = #{processDefinitionId}
      </if>
      <if test="processDefinitionKey != null">
        and D.KEY_ = #{processDefinitionKey}
      </if>
      <if test="processDefinitionKeyLike != null">
        and D.KEY_ like #{processDefinitionKeyLike}${wildcardEscapeClause}
      </if>
       <if test="processDefinitionKeyLikeIgnoreCase != null">
        and lower(D.KEY_) like #{processDefinitionKeyLikeIgnoreCase}${wildcardEscapeClause}
      </if>
      <if test="processDefinitionKeys != null &amp;&amp; processDefinitionKeys.size() &gt; 0">
        and D.KEY_ in
        <foreach item="item" index="index" collection="processDefinitionKeys" open="(" separator="," close=")">
          #{item}
        </foreach>
      </if>
      <if test="processDefinitionName != null">
        and D.NAME_ = #{processDefinitionName}
      </if>
      <if test="processDefinitionNameLike != null">
        and D.NAME_ like #{processDefinitionNameLike}${wildcardEscapeClause}
      </if>
      <if test="processCategoryInList != null &amp;&amp; processCategoryInList.size() &gt; 0">
        and D.CATEGORY_ IN
        <foreach item="processCategory" index="index" collection="processCategoryInList"
                 open="(" separator="," close=")">
          #{processCategory}
        </foreach>
      </if>
      <if test="processCategoryNotInList != null &amp;&amp; processCategoryNotInList.size() &gt; 0">
        and D.CATEGORY_ NOT IN
        <foreach item="processCategory" index="index" collection="processCategoryNotInList"
                 open="(" separator="," close=")">
          #{processCategory}
        </foreach>
      </if>
      <if test="deploymentId != null">
        and DEPLOY_P.DEPLOYMENT_ID_ = #{deploymentId}
      </if>
      <if test="deploymentIds != null &amp;&amp; deploymentIds.size() &gt; 0">
        and DEPLOY_P.DEPLOYMENT_ID_ IN
        <foreach item="deployment" index="index" collection="deploymentIds" 
                 open="(" separator="," close=")">
          #{deployment}
        </foreach>
      </if>
      <if test="processInstanceId != null">
        and RES.PROC_INST_ID_ = #{processInstanceId}
      </if>
      <if test="processInstanceIds != null &amp;&amp; processInstanceIds.size() &gt; 0">
        and RES.PROC_INST_ID_ IN
        <foreach item="processInstance" index="index" collection="processInstanceIds" 
                 open="(" separator="," close=")">
          #{processInstance}
        </foreach>
      </if>
      <if test="processInstanceBusinessKey != null">
        and HPI.BUSINESS_KEY_ = #{processInstanceBusinessKey}
      </if>
      <if test="processInstanceBusinessKeyLike != null">
        and HPI.BUSINESS_KEY_ like #{processInstanceBusinessKeyLike}${wildcardEscapeClause}
      </if>
       <if test="processInstanceBusinessKeyLikeIgnoreCase != null">
        and lower(HPI.BUSINESS_KEY_) like #{processInstanceBusinessKeyLikeIgnoreCase}${wildcardEscapeClause}
      </if>
      <if test="taskDefinitionKey != null">
        and RES.TASK_DEF_KEY_ = #{taskDefinitionKey}
      </if>
      <if test="taskDefinitionKeyLike != null">
        and RES.TASK_DEF_KEY_ like #{taskDefinitionKeyLike}${wildcardEscapeClause}
      </if>
      <if test="executionId != null">
        and RES.EXECUTION_ID_ = #{executionId}
      </if>
      <if test="taskName != null">
        and RES.NAME_ = #{taskName}
      </if>
      <if test="taskNameLike != null">
        and RES.NAME_ like #{taskNameLike}${wildcardEscapeClause}
      </if>
      <if test="taskNameLikeIgnoreCase != null">
        and lower(RES.NAME_) like #{taskNameLikeIgnoreCase}${wildcardEscapeClause}
      </if>
      <if test="taskNameList != null &amp;&amp; taskNameList.size() &gt; 0">
        and RES.NAME_ IN
        <foreach item="taskName" index="index" collection="taskNameList"
                 open="(" separator="," close=")">
          #{taskName}
        </foreach>
      </if>
      <if test="taskNameListIgnoreCase != null &amp;&amp; taskNameListIgnoreCase.size() &gt; 0">
        and lower(RES.NAME_) IN
        <foreach item="taskName" index="index" collection="taskNameListIgnoreCase"
                 open="(" separator="," close=")">
          #{taskName}
        </foreach>
      </if>
      <if test="taskParentTaskId != null">
        and RES.PARENT_TASK_ID_ = #{taskParentTaskId}
      </if>
      <if test="taskDescription != null">
        and RES.DESCRIPTION_ = #{taskDescription}
      </if>
      <if test="taskDescriptionLike != null">
        and RES.DESCRIPTION_ like #{taskDescriptionLike}${wildcardEscapeClause}
      </if>
       <if test="taskDescriptionLikeIgnoreCase != null">
        and lower(RES.DESCRIPTION_) like #{taskDescriptionLikeIgnoreCase}${wildcardEscapeClause}
      </if>
      <if test="taskDeleteReason != null">
        and RES.DELETE_REASON_ = #{taskDeleteReason}
      </if>
      <if test="taskDeleteReasonLike != null">
        and RES.DELETE_REASON_ like #{taskDeleteReasonLike}${wildcardEscapeClause}
      </if>
      <if test="taskOwner != null">
        and RES.OWNER_ = #{taskOwner}
      </if>
      <if test="taskOwnerLike != null">
        and RES.OWNER_ like #{taskOwnerLike}${wildcardEscapeClause}
      </if>
       <if test="taskOwnerLikeIgnoreCase != null">
        and lower(RES.OWNER_) like #{taskOwnerLikeIgnoreCase}${wildcardEscapeClause}
      </if>
      <if test="taskAssignee != null">
        and RES.ASSIGNEE_ = #{taskAssignee}
      </if>
      <if test="taskAssigneeLike != null">
        and RES.ASSIGNEE_ like #{taskAssigneeLike}${wildcardEscapeClause}
      </if>
      <if test="taskAssigneeLikeIgnoreCase != null">
        and lower(RES.ASSIGNEE_) like #{taskAssigneeLikeIgnoreCase}${wildcardEscapeClause}
      </if>
      <if test="taskAssigneeIds != null &amp;&amp; taskAssigneeIds.size() &gt; 0">
        and RES.ASSIGNEE_ IN
        <foreach item="assigneeId" index="index" collection="taskAssigneeIds" 
                 open="(" separator="," close=")">
          #{assigneeId}
        </foreach>
	  </if>
      <if test="taskPriority != null">
        and RES.PRIORITY_ = #{taskPriority}
      </if>
      <if test="taskMinPriority != null">
        and RES.PRIORITY_ &gt;= #{taskMinPriority}
      </if>
      <if test="taskMaxPriority != null">
        and RES.PRIORITY_ &lt;= #{taskMaxPriority}
      </if>
      <if test="unfinished">
        and RES.END_TIME_ is null
      </if>
      <if test="finished">
        and RES.END_TIME_ is not null
      </if>
      <if test="processFinished">
        and HPI.END_TIME_ is not null
      </if>
      <if test="processUnfinished">
        and HPI.END_TIME_ is null
      </if>
      <if test="dueDate != null">
        and RES.DUE_DATE_ = #{dueDate}
      </if>
      <if test="dueBefore != null">
        and RES.DUE_DATE_ &lt; #{dueBefore}
      </if>
      <if test="dueAfter != null">
        and RES.DUE_DATE_ &gt; #{dueAfter}
      </if>
      <if test="withoutDueDate">
        and RES.DUE_DATE_ is null
      </if>
      <if test="creationDate != null">
        and RES.START_TIME_ = #{creationDate}
      </if>
      <if test="creationBeforeDate != null">
        and RES.START_TIME_ &lt; #{creationBeforeDate}
      </if>
      <if test="creationAfterDate != null">
        and RES.START_TIME_ &gt; #{creationAfterDate}
      </if>
      <if test="completedDate != null">
        and RES.END_TIME_ = #{completedDate}
      </if>
      <if test="completedBeforeDate != null">
        and RES.END_TIME_ &lt; #{completedBeforeDate}
      </if>
      <if test="completedAfterDate != null">
        and RES.END_TIME_ &gt; #{completedAfterDate}
      </if>
      <if test="category != null">
        and RES.CATEGORY_ = #{category}
      </if>
      <if test="tenantId != null">
        and RES.TENANT_ID_ = #{tenantId}
      </if>
      <if test="tenantIdLike != null">
        and RES.TENANT_ID_ like #{tenantIdLike}${wildcardEscapeClause}
      </if>
      <if test="withoutTenantId">
        and (RES.TENANT_ID_ = '' or RES.TENANT_ID_ is null)
      </if>
      <if test="candidateUser != null || candidateGroups != null">
        and RES.ASSIGNEE_ is null
        and HI.TYPE_ = 'candidate'
        and
        (
          <if test="candidateUser != null">
            HI.USER_ID_ = #{candidateUser}
          </if>
          <if test="candidateUser != null &amp;&amp; candidateGroups != null &amp;&amp; candidateGroups.size() &gt; 0">
            or
          </if>
          <if test="candidateGroups != null &amp;&amp; candidateGroups.size() &gt; 0">
            HI.GROUP_ID_ IN
            <foreach item="group" index="index" collection="candidateGroups"
                     open="(" separator="," close=")">
              #{group}
            </foreach>
          </if>
        )
      </if>
      <if test="involvedUser != null">
        and
        (
          exists(select LINK.USER_ID_ from ${prefix}ACT_HI_IDENTITYLINK LINK where USER_ID_ = #{involvedUser} and LINK.TASK_ID_ = RES.ID_)
          or RES.ASSIGNEE_ = #{involvedUser}
          or RES.OWNER_ = #{involvedUser}
        )
      </if>
      <if test="involvedGroups != null &amp;&amp; involvedGroups.size() &gt; 0">
        and
        (
          HI.TYPE_ = 'participant'
          and
          HI.GROUP_ID_ IN
          <foreach item="group" index="index" collection="involvedGroups" open="(" separator="," close=")">
            #{group}
          </foreach>
        )
      </if>
      <foreach item="queryVar" collection="queryVariableValues" index="index">
        <if test="!queryVar.local">
          <!-- When process instance variable is queried for, taskId should be null -->
          and A${index}.TASK_ID_ is null
        </if>
        <if test="queryVar.name != null">
          <!-- Match-all variable-names when name is null -->
          and A${index}.NAME_= #{queryVar.name}
        </if>
        <if test="!queryVar.type.equals('null')">
          and A${index}.VAR_TYPE_ = #{queryVar.type}
        </if>
        <!-- Variable value -->
        <if test="queryVar.textValue != null &amp;&amp; queryVar.longValue == null &amp;&amp; queryVar.doubleValue == null">
          <choose>
            <when test="queryVar.operator.equals('EQUALS_IGNORE_CASE') || queryVar.operator.equals('NOT_EQUALS_IGNORE_CASE') || queryVar.operator.equals('LIKE_IGNORE_CASE')">
              and lower(A${index}.TEXT_)
            </when>
            <otherwise>
              and A${index}.TEXT_
            </otherwise>
          </choose> 
          <choose>
              <when test="queryVar.operator.equals('LIKE') || queryVar.operator.equals('LIKE_IGNORE_CASE')">LIKE</when>
              <otherwise><include refid="executionVariableOperator" /></otherwise>
          </choose>          
          #{queryVar.textValue}
          <choose>
            <when test="queryVar.operator.equals('LIKE') || queryVar.operator.equals('LIKE_IGNORE_CASE')">${wildcardEscapeClause}</when>
          </choose>
        </if>
        <if test="queryVar.textValue2 != null">
          and A${index}.TEXT2_ 
          <choose>
            <when test="queryVar.operator.equals('LIKE')">LIKE</when>
            <otherwise><include refid="executionVariableOperator" /></otherwise>
          </choose>          
          #{queryVar.textValue2}
          <choose>
            <when test="queryVar.operator.equals('LIKE')">${wildcardEscapeClause}</when>
          </choose>
        </if>
        <if test="queryVar.longValue != null">
          and A${index}.LONG_
          <include refid="executionVariableOperator" />
          #{queryVar.longValue}
        </if>
        <if test="queryVar.doubleValue != null">
          and A${index}.DOUBLE_ 
          <include refid="executionVariableOperator" />
          #{queryVar.doubleValue}
        </if>
        <!-- Null variable type -->
        <if test="queryVar.textValue == null &amp;&amp; queryVar.textValue2 == null &amp;&amp; queryVar.longValue == null &amp;&amp; queryVar.doubleValue == null">
          <choose>
            <when test="queryVar.operator.equals('NOT_EQUALS')">
              and (A${index}.TEXT_ is not null or A${index}.TEXT2_ is not null or A${index}.LONG_ is not null or A${index}.DOUBLE_ is not null or A${index}.BYTEARRAY_ID_ is not null)
            </when>
            <otherwise>
              and A${index}.TEXT_ is null and A${index}.TEXT2_ is null and A${index}.LONG_ is null and A${index}.DOUBLE_ is null and A${index}.BYTEARRAY_ID_ is null
            </otherwise>
          </choose>          
        </if>
      </foreach>
      <foreach item="orQueryObject" index="orIndex" collection="orQueryObjects">
        and 
        <trim prefix="(" prefixOverrides="OR" suffix=")">
          <if test="orQueryObject.taskId != null">
            RES.ID_ = #{orQueryObject.taskId}
          </if>
          <if test="orQueryObject.processDefinitionId != null">
            or RES.PROC_DEF_ID_ = #{orQueryObject.processDefinitionId}
          </if>
          <if test="orQueryObject.processDefinitionKey != null">
            or D_OR${orIndex}.KEY_ = #{orQueryObject.processDefinitionKey}
          </if>
          <if test="orQueryObject.processDefinitionKeyLike != null">
            or D_OR${orIndex}.KEY_ like #{orQueryObject.processDefinitionKeyLike}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.processDefinitionKeyLikeIgnoreCase != null">
            or lower(D_OR${orIndex}.KEY_) like #{orQueryObject.processDefinitionKeyLikeIgnoreCase}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.processDefinitionKeys != null &amp;&amp; orQueryObject.processDefinitionKeys.size() &gt; 0">
            or D_OR${orIndex}.KEY_ in
            <foreach item="item" index="index" collection="orQueryObject.processDefinitionKeys" open="(" separator="," close=")">
              #{item}
            </foreach>
          </if>
          <if test="orQueryObject.processDefinitionName != null">
            or D_OR${orIndex}.NAME_ = #{orQueryObject.processDefinitionName}
          </if>
          <if test="orQueryObject.processDefinitionNameLike != null">
            or D_OR${orIndex}.NAME_ like #{orQueryObject.processDefinitionNameLike}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.processCategoryInList != null &amp;&amp; orQueryObject.processCategoryInList.size() &gt; 0">
            or D_OR${orIndex}.CATEGORY_ IN
            <foreach item="processCategory" index="index" collection="orQueryObject.processCategoryInList"
                     open="(" separator="," close=")">
              #{processCategory}
            </foreach>
          </if>
          <if test="orQueryObject.processCategoryNotInList != null &amp;&amp; orQueryObject.processCategoryNotInList.size() &gt; 0">
            or D_OR${orIndex}.CATEGORY_ NOT IN
            <foreach item="processCategory" index="index" collection="orQueryObject.processCategoryNotInList"
                     open="(" separator="," close=")">
              #{processCategory}
            </foreach>
          </if>
          <if test="orQueryObject.deploymentId != null">
            or DEPLOY_P_OR${orIndex}.DEPLOYMENT_ID_ = #{orQueryObject.deploymentId}
          </if>
          <if test="orQueryObject.deploymentIds != null &amp;&amp; orQueryObject.deploymentIds.size() &gt; 0">
            or DEPLOY_P_OR${orIndex}.DEPLOYMENT_ID_ IN
            <foreach item="deployment" index="index" collection="orQueryObject.deploymentIds" 
                     open="(" separator="," close=")">
              #{deployment}
            </foreach>
          </if>
          <if test="orQueryObject.processInstanceId != null">
            or RES.PROC_INST_ID_ = #{orQueryObject.processInstanceId}
          </if>
          <if test="orQueryObject.processInstanceIds != null &amp;&amp; orQueryObject.processInstanceIds.size() &gt; 0">
            or RES.PROC_INST_ID_ IN
            <foreach item="processInstance" index="index" collection="orQueryObject.processInstanceIds" 
                     open="(" separator="," close=")">
              #{processInstance}
            </foreach>
          </if>
          <if test="orQueryObject.processInstanceBusinessKey != null">
            or HPI_OR${orIndex}.BUSINESS_KEY_ = #{orQueryObject.processInstanceBusinessKey}
          </if>
          <if test="orQueryObject.processInstanceBusinessKeyLike != null">
            or HPI_OR${orIndex}.BUSINESS_KEY_ like #{orQueryObject.processInstanceBusinessKeyLike}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.processInstanceBusinessKeyLikeIgnoreCase != null">
            or lower(HPI_OR${orIndex}.BUSINESS_KEY_) like #{orQueryObject.processInstanceBusinessKeyLikeIgnoreCase}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.taskDefinitionKey != null">
            or RES.TASK_DEF_KEY_ = #{orQueryObject.taskDefinitionKey}
          </if>
          <if test="orQueryObject.taskDefinitionKeyLike != null">
            or RES.TASK_DEF_KEY_ like #{orQueryObject.taskDefinitionKeyLike}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.executionId != null">
            or RES.EXECUTION_ID_ = #{orQueryObject.executionId}
          </if>
          <if test="orQueryObject.taskName != null">
            or RES.NAME_ = #{orQueryObject.taskName}
          </if>
          <if test="orQueryObject.taskNameLike != null">
            or RES.NAME_ like #{orQueryObject.taskNameLike}${wildcardEscapeClause}
          </if>
           <if test="orQueryObject.taskNameLikeIgnoreCase != null">
            or lower(RES.NAME_) like #{orQueryObject.taskNameLikeIgnoreCase}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.taskNameList != null &amp;&amp; orQueryObject.taskNameList.size() &gt; 0">
            or RES.NAME_ IN
            <foreach item="taskName" index="index" collection="orQueryObject.taskNameList"
                     open="(" separator="," close=")">
              #{taskName}
            </foreach>
          </if>
          <if test="orQueryObject.taskNameListIgnoreCase != null &amp;&amp; orQueryObject.taskNameListIgnoreCase.size() &gt; 0">
            or lower(RES.NAME_) IN
            <foreach item="taskName" index="index" collection="orQueryObject.taskNameListIgnoreCase"
                     open="(" separator="," close=")">
              #{taskName}
            </foreach>
          </if>
          <if test="orQueryObject.taskParentTaskId != null">
            or RES.PARENT_TASK_ID_ = #{orQueryObject.taskParentTaskId}
          </if>
          <if test="orQueryObject.taskDescription != null">
            or RES.DESCRIPTION_ = #{orQueryObject.taskDescription}
          </if>
          <if test="orQueryObject.taskDescriptionLike != null">
            or RES.DESCRIPTION_ like #{orQueryObject.taskDescriptionLike}${wildcardEscapeClause}
          </if>
           <if test="orQueryObject.taskDescriptionLikeIgnoreCase != null">
            or lower(RES.DESCRIPTION_) like #{orQueryObject.taskDescriptionLikeIgnoreCase}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.taskDeleteReason != null">
            or RES.DELETE_REASON_ = #{orQueryObject.taskDeleteReason}
          </if>
          <if test="orQueryObject.taskDeleteReasonLike != null">
            or RES.DELETE_REASON_ like #{orQueryObject.taskDeleteReasonLike}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.taskOwner != null">
            or RES.OWNER_ = #{orQueryObject.taskOwner}
          </if>
          <if test="orQueryObject.taskOwnerLike != null">
            or RES.OWNER_ like #{orQueryObject.taskOwnerLike}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.taskOwnerLikeIgnoreCase != null">
            or lower(RES.OWNER_) like #{orQueryObject.taskOwnerLikeIgnoreCase}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.taskAssignee != null">
            or RES.ASSIGNEE_ = #{orQueryObject.taskAssignee}
          </if>
          <if test="orQueryObject.taskAssigneeLike != null">
            or RES.ASSIGNEE_ like #{orQueryObject.taskAssigneeLike}${wildcardEscapeClause}
          </if>
           <if test="orQueryObject.taskAssigneeLikeIgnoreCase != null">
            or RES.ASSIGNEE_ like #{orQueryObject.taskAssigneeLikeIgnoreCase}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.taskAssigneeIds != null &amp;&amp; orQueryObject.taskAssigneeIds.size() &gt; 0">
	        or RES.ASSIGNEE_ IN
	        <foreach item="assigneeId" index="index" collection="orQueryObject.taskAssigneeIds" 
	                 open="(" separator="," close=")">
	          #{assigneeId}
	        </foreach>
		  </if>
          <if test="orQueryObject.taskPriority != null">
            or RES.PRIORITY_ = #{orQueryObject.taskPriority}
          </if>
          <if test="orQueryObject.taskMinPriority != null">
            or RES.PRIORITY_ &gt;= #{orQueryObject.taskMinPriority}
          </if>
          <if test="orQueryObject.taskMaxPriority != null">
            or RES.PRIORITY_ &lt;= #{orQueryObject.taskMaxPriority}
          </if>
          <if test="orQueryObject.unfinished">
            or RES.END_TIME_ is null
          </if>
          <if test="orQueryObject.finished">
            or RES.END_TIME_ is not null
          </if>
          <if test="orQueryObject.processFinished">
            or HPI_OR${orIndex}.END_TIME_ is not null
          </if>
          <if test="orQueryObject.processUnfinished">
            or HPI_OR${orIndex}.END_TIME_ is null
          </if>
          <if test="orQueryObject.dueDate != null">
            or RES.DUE_DATE_ = #{orQueryObject.dueDate}
          </if>
          <if test="orQueryObject.dueBefore != null">
            or RES.DUE_DATE_ &lt; #{orQueryObject.dueBefore}
          </if>
          <if test="orQueryObject.dueAfter != null">
            or RES.DUE_DATE_ &gt; #{orQueryObject.dueAfter}
          </if>
          <if test="orQueryObject.withoutDueDate">
            or RES.DUE_DATE_ is null
          </if>
          <if test="orQueryObject.creationDate != null">
            or RES.START_TIME_ = #{orQueryObject.creationDate}
          </if>
          <if test="orQueryObject.creationBeforeDate != null">
            or RES.START_TIME_ &lt; #{orQueryObject.creationBeforeDate}
          </if>
          <if test="orQueryObject.creationAfterDate != null">
            or RES.START_TIME_ &gt; #{orQueryObject.creationAfterDate}
          </if>
          <if test="orQueryObject.completedDate != null">
            or RES.END_TIME_ = #{orQueryObject.completedDate}
          </if>
          <if test="orQueryObject.completedBeforeDate != null">
            or RES.END_TIME_ &lt; #{orQueryObject.completedBeforeDate}
          </if>
          <if test="orQueryObject.completedAfterDate != null">
            or RES.END_TIME_ &gt; #{orQueryObject.completedAfterDate}
          </if>
          <if test="orQueryObject.category != null">
            or RES.CATEGORY_ = #{orQueryObject.category}
          </if>
          <if test="orQueryObject.tenantId != null">
            or RES.TENANT_ID_ = #{orQueryObject.tenantId}
          </if>
          <if test="orQueryObject.tenantIdLike != null">
            or RES.TENANT_ID_ like #{orQueryObject.tenantIdLike}${wildcardEscapeClause}
          </if>
          <if test="orQueryObject.withoutTenantId">
            or (RES.TENANT_ID_ = '' or RES.TENANT_ID_ is null)
          </if>
          <if test="orQueryObject.candidateUser != null || orQueryObject.candidateGroups != null">
            or (RES.ASSIGNEE_ is null
            and HI_OR${orIndex}.TYPE_ = 'candidate'
            and
            (
              <if test="orQueryObject.candidateUser != null">
                HI_OR${orIndex}.USER_ID_ = #{orQueryObject.candidateUser}
              </if>
              <if test="orQueryObject.candidateUser != null &amp;&amp; orQueryObject.candidateGroups != null &amp;&amp; orQueryObject.candidateGroups.size() &gt; 0">
                or
              </if>
              <if test="orQueryObject.candidateGroups != null &amp;&amp; orQueryObject.candidateGroups.size() &gt; 0">
                HI_OR${orIndex}.GROUP_ID_ IN
                <foreach item="group" index="index" collection="orQueryObject.candidateGroups"
                         open="(" separator="," close=")">
                  #{group}
                </foreach>
              </if>
            ))
          </if>
          <if test="orQueryObject.involvedUser != null">
            or
            (
              exists(select LINK.USER_ID_ from ${prefix}ACT_HI_IDENTITYLINK LINK where USER_ID_ = #{orQueryObject.involvedUser} and LINK.TASK_ID_ = RES.ID_)
              or RES.ASSIGNEE_ = #{orQueryObject.involvedUser}
              or RES.OWNER_ = #{orQueryObject.involvedUser}
            )
          </if>
          <if test="orQueryObject.involvedGroups != null &amp;&amp; orQueryObject.involvedGroups.size() &gt; 0">
            or
            (
              HI_OR${orIndex}.TYPE_ = 'participant'
              and
              HI_OR${orIndex}.GROUP_ID_ IN
              <foreach item="group" index="index" collection="orQueryObject.involvedGroups" open="(" separator="," close=")">
                #{group}
              </foreach>
            )
          </if>
          <foreach item="queryVar" collection="orQueryObject.queryVariableValues" index="index">
            or
            <trim prefix="(" prefixOverrides="AND" suffix=")">
              <choose>
                <when test="!queryVar.local">
                  <bind name="orLocal" value="''" />
                  <!-- When process instance variable is queried for, taskId should be null -->
                  and A_OR${orIndex}.TASK_ID_ is null
                </when>
                <otherwise>
                  <bind name="orLocal" value="'L_'" />
                </otherwise>
              </choose>
              <if test="queryVar.name != null">
                <!-- Match-all variable-names when name is null -->
                and A_${orLocal}OR${orIndex}.NAME_= #{queryVar.name}
              </if>
              <if test="!queryVar.type.equals('null')">
                and A_${orLocal}OR${orIndex}.VAR_TYPE_ = #{queryVar.type}
              </if>
              <!-- Variable value -->
              <if test="queryVar.textValue != null &amp;&amp; queryVar.longValue == null &amp;&amp; queryVar.doubleValue == null">
                <choose>
                  <when test="queryVar.operator.equals('EQUALS_IGNORE_CASE') || queryVar.operator.equals('NOT_EQUALS_IGNORE_CASE') || queryVar.operator.equals('LIKE_IGNORE_CASE')">
                    and lower(A_${orLocal}OR${orIndex}.TEXT_)
                  </when>
                  <otherwise>
                    and A_${orLocal}OR${orIndex}.TEXT_
                  </otherwise>
                </choose> 
                <choose>
                    <when test="queryVar.operator.equals('LIKE') || queryVar.operator.equals('LIKE_IGNORE_CASE')">LIKE</when>
                    <otherwise><include refid="executionVariableOperator" /></otherwise>
                </choose>          
                #{queryVar.textValue}
                <choose>
                  <when test="queryVar.operator.equals('LIKE') || queryVar.operator.equals('LIKE_IGNORE_CASE')">${wildcardEscapeClause}</when>
                </choose>
              </if>
              <if test="queryVar.textValue2 != null">
                and A_${orLocal}OR${orIndex}.TEXT2_ 
                <choose>
                  <when test="queryVar.operator.equals('LIKE')">LIKE</when>
                  <otherwise><include refid="executionVariableOperator" /></otherwise>
                </choose>          
                #{queryVar.textValue2}
                <choose>
                  <when test="queryVar.operator.equals('LIKE')">${wildcardEscapeClause}</when>
                </choose>
              </if>
              <if test="queryVar.longValue != null">
                and A_${orLocal}OR${orIndex}.LONG_
                <include refid="executionVariableOperator" />
                #{queryVar.longValue}
              </if>
              <if test="queryVar.doubleValue != null">
                and A_${orLocal}OR${orIndex}.DOUBLE_ 
                <include refid="executionVariableOperator" />
                #{queryVar.doubleValue}
              </if>
              <!-- Null variable type -->
              <if test="queryVar.textValue == null &amp;&amp; queryVar.textValue2 == null &amp;&amp; queryVar.longValue == null &amp;&amp; queryVar.doubleValue == null">
                <choose>
                  <when test="queryVar.operator.equals('NOT_EQUALS')">
                    and (A_${orLocal}OR${orIndex}.TEXT_ is not null or A_${orLocal}OR${orIndex}.TEXT2_ is not null or A_${orLocal}OR${orIndex}.LONG_ is not null or A_${orLocal}OR${orIndex}.DOUBLE_ is not null or A_${orLocal}OR${orIndex}.BYTEARRAY_ID_ is not null)
                  </when>
                  <otherwise>
                    and A_${orLocal}OR${orIndex}.TEXT_ is null and A_${orLocal}OR${orIndex}.TEXT2_ is null and A_${orLocal}OR${orIndex}.LONG_ is null and A_${orLocal}OR${orIndex}.DOUBLE_ is null and A_${orLocal}OR${orIndex}.BYTEARRAY_ID_ is null
                  </otherwise>
                </choose>          
              </if>
            </trim>
          </foreach>
        </trim>
      </foreach>
    </where>
  </sql>

重点

xml 复制代码
<if test="processInstanceId != null">
        and RES.PROC_INST_ID_ = #{processInstanceId}
</if>

当此处传入了一个空的实例id时,就会导致发生异常,拼接出来的查表操作就变成了不带where的全表扫描!!!

这也叫解释了为神马多次重启系统后时不时无响应。。。该用户在进行错误操作时,时不时导致系统发生GC。。。

古人也真是给我们留下了很多惊喜。

转载请注明出处:https://lizhiyong.blog.csdn.net/article/details/149923948

相关推荐
麦兜*2 分钟前
Spring Boot 与 Ollama 集成部署私有LLM服务 的完整避坑指南,涵盖 环境配置、模型管理、性能优化 和 安全加固
java·spring boot·后端·安全·spring cloud·性能优化
leo__5205 分钟前
Java的NIO体系详解
java·python·nio
烟沙九洲5 分钟前
服务之间远程Feign调用,出现参数丢失
java·spring boot
Yang-Never8 分钟前
Kotlin协程 ->launch构建协程以及调度源码详解
android·java·开发语言·kotlin·android studio
极客BIM工作室12 分钟前
C++返回值优化(RVO):高效返回对象的艺术
java·开发语言·c++
用户849137175471612 分钟前
JustAuth实战系列(第1期):项目概览与价值分析
java·架构·开源
自由的疯32 分钟前
Java 17 新特性之 instanceof 运算符
java·后端·架构
自由的疯36 分钟前
Java 17 新特性之 Switch 表达式改进
java·后端·架构
玄昌盛不会编程1 小时前
LeetCode——2683. 相邻值的按位异或
java·算法·leetcode
青云交1 小时前
Java 大视界 -- Java 大数据在智能医疗电子病历数据分析与临床决策支持中的应用(382)
java·大数据·数据分析·flink·电子病历·智能医疗·临床决策