gpt4 book ai didi

oracle - 如何等待 dbms_scheduler 作业完成

转载 作者:行者123 更新时间:2023-12-02 00:08:08 26 4
gpt4 key购买 nike

使用 Oracle 11.2

嗨,

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

目前我不得不休眠并循环轮询表 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;

它确实有效,但看起来像是一些可怕的黑客。

有没有更好的方法:

  1. 等待所有作业完成。
  2. 一次运行四个作业,并在其中一个运行作业完成后立即启动一个新作业。
  3. 如果一项作业失败或损坏,则抛出异常。

最佳答案

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;

关于oracle - 如何等待 dbms_scheduler 作业完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28546654/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com