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

Oracle APEX中DBMS_SCHEDULER遇浏览器刷新重复生成作业求助

问题分析与解决方案

核心问题

Apex仪表板中通过按钮触发的DBMS_SCHEDULER作业,近期出现浏览器/页面刷新时也会重复触发的情况,导致同一时间生成多个作业实例,仅需保留按钮点击触发的逻辑。

排查方向与解决步骤

1. 修正动态动作触发条件

检查触发作业的动态动作配置:

  • 确保触发类型仅为按钮点击,不要勾选页面加载、刷新或其他无关触发事件;
  • 确认动态动作仅绑定到目标按钮,未误绑定到页面全局事件。

2. 切换请求方式为POST

若按钮使用GET方式提交请求,浏览器刷新会重发上次请求导致重复执行作业:

  • 修改按钮的Action属性为Submit Page,并确保请求方法为POST;
  • 若使用AJAX动态动作执行PL/SQL,确认未手动将请求方式改为GET(Apex默认AJAX执行PL/SQL为POST)。

3. 优化PL/SQL代码,避免重复触发

当前代码的循环逻辑和无锁处理会导致重复请求时多次触发作业,调整如下:

  • 使用FOR UPDATE SKIP LOCKED防止并发请求选取同一记录;
  • 处理前更新记录状态为IN_PROGRESS,避免后续请求重复处理;
  • 移除不必要的循环,改为单次处理逻辑(原循环会在单次请求中多次触发作业,刷新后会再次执行整个循环)。

修改后的PL/SQL示例:

BEGIN
    DECLARE
        v_current_group AUTOMATION_execution_plan.LOGICAL_GROUP_NAME%TYPE;
    BEGIN
        -- 加锁跳过已被处理的记录,防止并发重复选取
        SELECT LOGICAL_GROUP_NAME 
          INTO v_current_group 
          FROM AUTOMATION_execution_plan 
         WHERE seq_number = :SEQ_NUM 
           AND status = 'WAITING' 
      ORDER BY execution_group_seq, execution_method_seq 
        FETCH NEXT 1 ROWS ONLY
          FOR UPDATE SKIP LOCKED;

        -- 更新状态为执行中,避免后续请求重复处理
        UPDATE AUTOMATION_execution_plan
           SET status = 'IN_PROGRESS'
         WHERE LOGICAL_GROUP_NAME = v_current_group
           AND seq_number = :SEQ_NUM;
        COMMIT;

        -- 设置作业参数并执行
        DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('PRD_APEX_OS_RUNNER_ARGS',1,'start -p UnityClone122 -t ACDEV -l SOLR_Post_Clone -k <keypass>' );
        DBMS_SCHEDULER.RUN_JOB ('PRD_APEX_OS_RUNNER_ARGS' , false);      
    EXCEPTION 
        WHEN NO_DATA_FOUND THEN 
            NULL; -- 无等待处理的记录时直接退出
        WHEN OTHERS THEN 
            -- 建议将错误日志写入专门的表,替代dbms_output方便排查
            INSERT INTO AUTOMATION_ERROR_LOG (error_message, log_timestamp)
            VALUES (SQLERRM, SYSTIMESTAMP);
            COMMIT;
    END;
END;

4. 限制作业并发执行

在触发作业前检查是否已有同名称作业在运行,避免重复启动:

DECLARE
    v_job_running NUMBER;
BEGIN
    SELECT COUNT(*)
      INTO v_job_running
      FROM DBA_SCHEDULER_RUNNING_JOBS
     WHERE JOB_NAME = 'PRD_APEX_OS_RUNNER_ARGS'
       AND OWNER = 'XXARW_AUTOMATION';

    IF v_job_running = 0 THEN
        DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('PRD_APEX_OS_RUNNER_ARGS',1,'start -p UnityClone122 -t ACDEV -l SOLR_Post_Clone -k <keypass>' );
        DBMS_SCHEDULER.RUN_JOB ('PRD_APEX_OS_RUNNER_ARGS' , false);
    END IF;
END;

5. 添加页面防重复提交令牌

在Apex页面中创建隐藏项(如PXX_SUBMIT_TOKEN),每次按钮点击时生成唯一UUID:

  • 在按钮的动态动作中,先生成令牌并写入隐藏项;
  • 执行PL/SQL前验证令牌是否未被使用,使用后标记为已用(可存入临时表或会话变量);
  • 刷新页面时令牌会重置,避免重复提交。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 21:34:54