ECM 之 DM_WORKFLOW_E_TRANS_MAX_OUTPUT_CNT_EXCEEDED 错误分析与解决

2012-11-10 09:25:51,146 ERROR [STDERR] DfException:: THREAD: http-0.0.0.0-9160-1; MSG: [DM_WORKFLOW_E_TRANS_MAX_OUTPUT_CNT_EXCEEDED]error:  "A maximum of 1 output ports can be selected. (The maximum is defined in the activity's transition_max_output_cnt attribute.)"; ERRORCODE: 100; NEXT: null
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.impl.docbase.DocbaseExceptionMapper.newException(DocbaseExceptionMapper.java:57)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.impl.connection.docbase.MessageEntry.getException(MessageEntry.java:39)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.impl.connection.docbase.DocbaseMessageManager.getException(DocbaseMessageManager.java:137)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.impl.connection.docbase.netwise.NetwiseDocbaseRpcClient.checkForMessages(NetwiseDocbaseRpcClient.java:305)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.impl.connection.docbase.netwise.NetwiseDocbaseRpcClient.applyForBool(NetwiseDocbaseRpcClient.java:349)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection$1.evaluate(DocbaseConnection.java:1108)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.evaluateRpc(DocbaseConnection.java:1046)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.applyForBool(DocbaseConnection.java:1101)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.apply(DocbaseConnection.java:1086)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.impl.docbase.DocbaseApi.witemSetOutput(DocbaseApi.java:1240)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.DfWorkitem.setOutput(DfWorkitem.java:406)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.fc.client.DfWorkitem.setOutputByActivities(DfWorkitem.java:879)
2012-11-10 09:25:51,147 ERROR [STDERR] 	at com.documentum.bpm.DfWorkitemEx___PROXY.setOutputByActivities(DfWorkitemEx___PROXY.java)

做使用ECM抛流程时, 执行完成后报如上错误。

以上是错误的详情。


解决思路:

  1. 从报错的msg来看, 是流程的出口多了。在activity 中定义的最大值是 “1”.
    通过Process Builder查找到这一个流程关卡的 r_object_id,再使用DQL获得transition_max_output_cnt的值。
    select transition_max_output_cnt from dm_activity where r_object_id='4cXXXXXXXXXXXXXXXX'.
    得到的值是 “1”, 和提示的信息正好吻合。
    其实这个值也就是在activity 配置页面的Transition tab 的 Select up to [] next activities  选项的方括号中的值。
  2. 既然定义的最大值是1, 那实际调用时, 传入的output port又是几呢?
    这里得明确一下output port 的定义。 output port 是指流程模板(Process)定义的当前节点的流出口, 其实就是从当前节点出发到下一个节点的连接线的条数(forword or reject)
    通过追踪以上错误的日志,反编译代码, 得到:
    output port 的取值是从dm_process(流程模板) 中获取的。
    因为这里的状况是: 从当前节点到相同下一个节点有两条线(成功和失败的), 所以取到的output port的值就有两个(分别为 Output:0 和Output:1)

    		IDfWorkitem workitemid = (IDfWorkitem)session.getObjectByQualification("dmi_workitem where r_object_id='"+sWorkItemId+"'");
    		IDfList forwardActList = workitemid.getForwardActivities();
    		if(workitemid.getRuntimeState() != IDfWorkitem.DF_WI_STATE_ACQUIRED) {
    			workitemid.acquire();
    		}
    		
    		IDfActivity actold = (IDfActivity)forwardActList.get(0);
    	    IDfList actList = new DfList();
    	    actList.append(actold);
    		//workitemid.setOutputByActivities(actList);
            IDfList outputPorts = new DfList();
            IDfId workflowId = session.getIdByQualification("dm_workflow where r_object_id='4d00000b8001f147'");
            IDfWorkflow wf = (IDfWorkflow)session.getObject(workflowId);
            IDfId procId = wf.getProcessId();
            System.out.println("Process id="+procId.toString());
            IDfProcess process = (IDfProcess)session.getObject(procId);
            int seqno = getActSeqno(workitemid);
            int seqnoIndex = wf.findInt("r_act_seqno", seqno);
            if(seqno >= 0)
            {
                String aliasName = wf.getActName(seqnoIndex);
                for(int j = 0; j < actList.getCount(); j++)
                {
                    IDfActivity act = (IDfActivity)actList.get(j);
                    IDfId actID = act.getObjectId();
                    IDfList actNames = new DfList();
                    int numActs = process.getActivityCount();
                    for(int i = 0; i < numActs; i++)
                        if(process.getActivityDefId(i).equals(actID))
                            actNames.appendString(process.getActivityName(i));
    
                    for(int i = 0; i < process.getProcessLinkCount(); i++)
                    {
                        if(process.getLinkSrcActivity(i).compareTo(aliasName) != 0)
                            continue;
                        System.out.println("process.getLinkSrcActivity(i)="+process.getLinkSrcActivity(i));
                        String destActName = process.getLinkDestActivity(i);
                        int destListIndex = actNames.findStringIndex(destActName);
                        if(destListIndex > -1)
                        {
                            String srcPort = process.getLinkSrcPort(i);
                            outputPorts.appendString(srcPort);
                        }
                    }
    
                }
    
            }


  3. 从以上得出, 两个值不相等。原因找到。
    通过Porcess Builder把1 的值修改为2.(也可以check out之后, 使用DQL更新dm_activity)

  4. 理论上修改之后,流程应该能够跑过。 但是,发现改过之后依然报同样的错误。
    再继续找原因,使用DQL查看一下当前 dm_workflow 的信息
    select * from dm_workflow where r_object_id='4dXXXXXXXXXXX'
    发现dm_workflow中有记录流程模板的id号 process_id
    再使用DQL查一下, 对应的流程模板的 id
    select * from dm_process where object_name = 'XXXXXXXXX'

    发现两者不一样。
    也就是说, 通过Process Builder 修改流程模板之后, 流程模板进版, 对应的r_object_id号就更新了。
    没办法使用SQL更新dm_workflow的process_id
    update dm_workflow object  set process_id='4bXXXXXXXXXX' where r_object_id='4dXXXXXXXXXXXXXX'


  5. 尝试一下, 还是不行。
    应该还有其他记录有旧流程模板的信息。 猜测一下, 应该是dmi_workitem里的了(dm_activity的实例)
    使用SQL的db 查询(DQL看不了足够的信息)
    Select * From Dmi_Workitem_R Where R_Object_Id='4aXXXXXXXX';
    Select * From Dmi_Workitem_S Where R_Object_Id='4aXXXXXXXX';
    Select * From Dmi_Workitem_Sp Where R_Object_Id='4aXXXXX';
    Select * From Dmi_Workitem_Rp Where R_Object_Id='4aXXXXXXX';
    果不其然, R_Act_Def_Id 这两个栏位分别记录 了旧的dm_activity的 id.
    同样使用,DQL更改。
    成功了。。。。
  6. 遗留的问题:
    		IDfList forwardActList = workitemid.getForwardActivities();
    		if(workitemid.getRuntimeState() != IDfWorkitem.DF_WI_STATE_ACQUIRED) {
    			workitemid.acquire();
    		}		
    		IDfActivity forwardAct = (IDfActivity)forwardActList.get(0);
    	    IDfList actList = new DfList();
    	    actList.append(forwardAct);
    	    workitemid.setOutputByActivities(actList);
                workitemid.complete();
    

             这里明明指定走的是成功的那条路线, 为什么还要去找失败的那条呢?



你可能感兴趣的:(ECM 之 DM_WORKFLOW_E_TRANS_MAX_OUTPUT_CNT_EXCEEDED 错误分析与解决)