加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

oracle – 如何等待dbms_scheduler作业完成

发布时间:2020-12-12 13:14:47 所属栏目:百科 来源:网络整理
导读:使用Oracle 11.2 嗨, 这是我想要做的:我正在使用dbms_scheduler安排作业.要安排的作业数量不固定,最多可以同时运行4个作业.安排作业的过程应该等到所有作业完成.如果一个作业失败,“计划”过程也应该失败,并且应该从调度程序中删除所有剩余的计划作业. 目前
使用Oracle 11.2

嗨,

这是我想要做的:我正在使用dbms_scheduler安排作业.要安排的作业数量不固定,最多可以同时运行4个作业.安排作业的过程应该等到所有作业完成.如果一个作业失败,“计划”过程也应该失败,并且应该从调度程序中删除所有剩余的计划作业.

目前我不得不在循环中睡眠和轮询表user_scheduler_jobs.

我是PL / SQL的新手而且缺乏经验,所以请不要对我太苛刻;)

到目前为止,这是我的代码.

首先是用于安排作业的代码段:

BEGIN
  FOR r IN (SELECT p_values FROM some_table WHERE flag = 0 )
  LOOP
    --  count running jobs
    SELECT count(*) INTO v_cnt
    FROM user_scheduler_jobs
    WHERE job_name LIKE 'something%';

    /*
    If max number of parallel jobs is reached,then wait before starting a new one.
    */
    WHILE v_cnt >= l_max_parallel_jobs
    LOOP

      dbms_lock.sleep(10);

      SELECT count(*) INTO v_cnt
      FROM user_scheduler_jobs
      WHERE job_name LIKE 'something%' AND state = 'RUNNING';

      SELECT count(*) INTO v_cnt_failures
      FROM user_scheduler_jobs
      WHERE job_name LIKE 'something%' AND state = 'FAILED' OR state = 'BROKEN';

      IF v_cnt_failures > 0 THEN RAISE some_exception; END IF;

    END LOOP;

    -- Start a new Job
    v_job_name := 'something_someting_' || p_values;
    v_job_action := 'begin user.some_procedure(''' || r.p_values || '''); end;';

    dbms_scheduler.create_job(job_name   => v_job_name,job_type   => 'PLSQL_BLOCK',job_action => v_job_action,comments   => 'Some comment ' || v_job_name,enabled    => FALSE,auto_drop  => FALSE);

    dbms_scheduler.set_attribute(NAME => v_job_name,ATTRIBUTE => 'max_failures',VALUE => '1');

    dbms_scheduler.set_attribute(NAME => v_job_name,ATTRIBUTE => 'max_runs',VALUE => '1');

    dbms_scheduler.enable(v_job_name);

    v_job_count := v_job_count + 1;

    -- array for all jobs
    v_jobs_aat(v_job_count) := v_job_name;

  END LOOP;

  -- ... Wait till all jobs have finisched. 

  check_queue_completion(v_jobs_aat); -- see procedure below
END;

等待最后四个工作的程序已经完成:

PROCEDURE check_queue_completion(p_jobs_aat IN OUT t_jobs_aat) AS
  v_state user_scheduler_jobs.state%TYPE;
  v_index PLS_INTEGER;
  v_done BOOLEAN := TRUE;

  -- Exceptions
  e_job_failure EXCEPTION;
BEGIN

  WHILE v_done
  LOOP

    v_done := FALSE;

    FOR i IN p_jobs_aat.first..p_jobs_aat.last
    LOOP

      SELECT state INTO v_state FROM user_scheduler_jobs WHERE job_name = p_jobs_aat(i);

      --dbms_output.put_line('Status: ' || v_state);

      CASE

        WHEN v_state = 'SUCCEEDED' OR v_state = 'COMPLETED' THEN
        dbms_output.put_line(p_jobs_aat(i) || ' SUCCEEDED');
        dbms_scheduler.drop_job(job_name => p_jobs_aat(i),force => TRUE);
        p_jobs_aat.delete(i);

        WHEN v_state = 'FAILED' OR v_state = 'BROKEN' THEN
        --Exception ausl?sen
        dbms_output.put_line(p_jobs_aat(i) || ' FAILED');
        RAISE e_job_failure;

        WHEN v_state = 'RUNNING' OR v_state = 'RETRY SCHEDULED' THEN
        NULL;
        dbms_output.put_line(p_jobs_aat(i) || ' RUNNING or RETRY SCHEDULED');
        v_done := TRUE;

      /*DISABLED,SCHEDULED,REMOTE,CHAIN_STALLED*/
      ELSE
        dbms_output.put_line(p_jobs_aat(i) || ' ELSE');
        dbms_scheduler.drop_job(job_name => p_jobs_aat(i),force => TRUE);
        p_jobs_aat.delete(i);
      END CASE;

    END LOOP;

    hifa.gen_sleep(30);

  END LOOP;

  IF p_jobs_aat.count > 0 THEN delete_jobs_in_queue(p_jobs_aat); END IF;

  EXCEPTION WHEN e_job_failure THEN
  delete_jobs_in_queue(p_jobs_aat);
  RAISE_APPLICATION_ERROR(-20500,'some error message');

END check_queue_completion;

这样做的伎俩,但它似乎是一些可怕的黑客.

是不是有更好的方法:

>等到所有工作完成.
>一次运行四个作业,并在其中一个正在运行的作业完成后立即启动一个新作业.
>如果一个作业失败或被破坏,则抛出异常.

解决方法

DECLARE
  cnt NUMBER:=1;
BEGIN
  WHILE cnt>=1
  LOOP
    SELECT count(1) INTO cnt FROM dba_scheduler_running_jobs srj
    WHERE srj.job_name IN ('TEST_JOB1','TEST_JOB2');
    IF cnt>0 THEN
      dbms_lock.sleep (5);
    END IF;
  END LOOP;
  dbms_output.put_line('ASASA');  
END;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读