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; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |