You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Progress运行存储过程提示-s stack exceeded告警问题求助

你遇到的是OpenEdge ABL的锁等待超时错误,触发原因是你加了EXCLUSIVE-LOCK的目标记录,在数据库设置的锁等待阈值内被其他会话持有,无法被当前会话获取。以下是常见触发原因和修复方案:

触发原因1:其他并行会话持有目标记录锁

你操作的V_Acct表对应记录,可能同时被其他业务流程、定时任务、人工操作持有排他锁,你的会话等待超时触发报错。
修复方案:在FOR EACH语句中添加NO-WAIT参数,获取锁失败时跳过对应记录并留痕,后续批量重试:

/* 仅展示修改后的FOR EACH部分,其余逻辑保持不变 */
FOR EACH V_Acct
    WHERE V_Acct.Company = '123'
        AND V_Acct.ReceiptType = 'U'
        AND V_Acct.ReferenceNr = integer(TRIM(ENTRY(1,cData,';')))
        AND V_Acct.xInfo = ''
    EXCLUSIVE-LOCK NO-WAIT:

    IF LOCKED(V_Acct) THEN DO:
        /* 可自行调整为写入日志文件的逻辑,方便后续重试 */
        MESSAGE "获取锁失败,ReferenceNr:" TRIM(ENTRY(1,cData,';')) VIEW-AS ALERT-BOX WARNING.
        NEXT.
    END.

    V_Acct.xInfo = 'VGF00000000000000'.
END.

触发原因2:事务粒度过大

当前代码所有修改都在一个隐式大事务中,所有修改过的记录锁都会持有到整个循环结束才释放,数据量较大时锁持有时间过长,大幅提升冲突概率。
修复方案:按批次提交事务,缩短锁持有时间:

/* 头部添加计数变量 */
DEFINE VARIABLE iCount AS INTEGER NO-UNDO INITIAL 0.

repeat:
    if keyfunction(lastkey) = "end-error" then leave.
    process events.

    import unformatted cData.
    iCount = iCount + 1.

    FOR EACH V_Acct
        WHERE V_Acct.Company = '123'
            AND V_Acct.ReceiptType = 'U'
            AND V_Acct.ReferenceNr = integer(TRIM(ENTRY(1,cData,';')))
            AND V_Acct.xInfo = ''
        EXCLUSIVE-LOCK:
        
        V_Acct.xInfo = 'VGF00000000000000'.
    END.

    /* 每处理100条提交一次,可根据实际业务调整批次大小 */
    IF iCount MOD 100 = 0 THEN DO:
        COMMIT.
        iCount = 0.
    END.
END.

/* 循环结束提交剩余批次 */
COMMIT.

触发原因3:查询索引缺失

如果V_Acct表没有覆盖Company、ReceiptType、ReferenceNr、xInfo的联合索引,查询会扫描大量不匹配的记录并加锁,额外增加锁冲突概率。
修复方案:联系DBA添加对应查询索引,缩小锁定的记录范围。


内容的提问来源于stack exchange,提问作者Smokus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 19:54:07