如何在多个实例中创建到 运行 的异步 Oracle 作业
How to create a async Oracle job to run in multiple instances
我已经创建了下一个程序和后续的 Oracle JOB:
BEGIN
DBMS_SCHEDULER.create_program (program_name => 'myProg',
program_action => 'myProc',
program_type => 'STORED_PROCEDURE',
number_of_arguments => 3,
enabled => FALSE);
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 1,
argument_type => 'NUMBER');
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 2,
argument_type => 'NUMBER');
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 3,
argument_type => 'NUMBER',
DEFAULT_VALUE => NULL);
DBMS_SCHEDULER.create_job ('myJob',
program_name => 'myProg',
enabled => FALSE,
comments => 'Send data');
DBMS_SCHEDULER.SET_ATTRIBUTE ('myJob', 'PARALLEL_INSTANCES', TRUE);
DBMS_SCHEDULER.SET_ATTRIBUTE ('myJob',
'logging_level',
DBMS_SCHEDULER.LOGGING_FULL);
END;
/
现在,我有一个用户可以 run/execute 调用下一个过程的作业:
PROCEDURE runJOB(param1 IN PLS_INTEGER,
param2 IN PLS_INTEGER DEFAULT NULL,
param3 IN PLS_INTEGER DEFAULT NULL)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
DBMS_SCHEDULER.enable ('myProg');
DBMS_SCHEDULER.set_job_argument_value ('myJob', 1, TO_CHAR (param1));
DBMS_SCHEDULER.set_job_argument_value ('myJob', 2, TO_CHAR (param2));
DBMS_SCHEDULER.set_job_argument_value ('myJob', 3, TO_CHAR (param3));
--DBMS_SCHEDULER.enable ('myJob');
DBMS_SCHEDULER.RUN_JOB (JOB_NAME => 'myJob', USE_CURRENT_SESSION => FALSE);
--DBMS_SCHEDULER.disable ('myJob');
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END runJOB;
我的问题是什么?
- 我需要 运行 异步模式下的作业。这就是为什么我有一个
enable
或 run_job
使用 USE_CURRENT_SESSION
参数
FALSE
。我认为这可行。
- 我需要执行同一个作业的多个实例,首先
不同的用户,同时。例如,用户 A 调用
runJOB
程序。该作业可以在 20 秒内 运行。在这20
秒,用户 B 可以在不同的会话中调用相同的过程。
这就是我尝试使用 PARALLEL_INSTANCES
属性的原因,但是
我只有一次执行。我认为 Oracle 认为这项工作是
运行ning,所以放弃第二次尝试运行。
在恢复中,我需要一个必须在异步模式下同时执行多个实例的作业。
在为两个实例执行作业 "double" 后,我只在 user_SCHEDULER_JOB_RUN_DETAILS
table 中获得一条记录,但是 2 为两个不同的用户(SGSS 和 EX01882_BD)
52367532 26/12/2016 12:08:44,584878 +00:00 SGSS myJob DEFAULT_JOB_CLASS RUN SUCCEEDED (HugeClob)
52364238 26/12/2016 12:08:36,529539 +00:00 SGSS myJob DEFAULT_JOB_CLASS ENABLE EX01882_BD (HUGECLOB)
52367534 26/12/2016 12:08:34,302807 +00:00 SGSS myJob DEFAULT_JOB_CLASS ENABLE SGSS (HUGECLOB)
有什么帮助吗?
注:
我不能使用与此解决方案 (How run two or more instances of an oracle job in the same time?) 中不同的作业名称,因为作业已经创建并且调用此作业的用户没有创建权限。
DBMS_SCHEDULER.RUN_JOB (JOB_NAME => 'myJob', USE_CURRENT_SESSION =>
FALSE);
现在,检查 documentation:
This specifies whether or not the job run should occur in the same
session that the procedure was invoked from.
When use_current_session is set to TRUE:
The job runs as the user who called RUN_JOB, or in the case of a local external job with a credential, the user named in the
credential.
You can test a job and see any possible errors on the command line.
run_count, last_start_date, last_run_duration, and failure_count are not updated.
RUN_JOB can be run in parallel with a regularly scheduled job run.
When use_current_session is set to FALSE:
The job runs as the user who is the job owner.
You need to check the job log to find error information.
run_count, last_start_date, last_run_duration, and failure_count are updated.
RUN_JOB fails if a regularly scheduled job is running.
解决方案:Event-Based Jobs
GRANT AQ_ADMINISTRATOR_ROLE TO USERA;
GRANT EXECUTE ON DBMS_SCHEDULER TO USERA;
GRANT EXECUTE ON sys.DBMS_SCHEDULER TO USERA;
GRANT EXECUTE ON sys.DBMS_ISCHED TO USERA;
GRANT CREATE JOB TO USERA;
GRANT CREATE EXTERNAL JOB TO USERA;
CREATE OR REPLACE TYPE t_event_queue_payload AS OBJECT (
event_name VARCHAR2(30)
);
BEGIN
-- Create a queue table to hold the event queue.
DBMS_AQADM.create_queue_table (
queue_table => 'event_queue_tab',
queue_payload_type => 't_event_queue_payload',
multiple_consumers => TRUE,
comment => 'Comments');
--Create the event queue.
DBMS_AQADM.create_queue (queue_name => 'event_queue',
queue_table => 'event_queue_tab');
-- Start the event queue.
DBMS_AQADM.start_queue (queue_name => 'event_queue');
END;
/
BEGIN
DBMS_SCHEDULER.create_program (
program_name => 'myProg',
program_action => 'USERA.PACKAGE.myProc',
program_type => 'STORED_PROCEDURE',
number_of_arguments => 3,
enabled => FALSE);
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 1,
argument_type => 'NUMBER');
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 2,
argument_type => 'NUMBER');
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 3,
argument_type => 'NUMBER',
DEFAULT_VALUE => NULL);
DBMS_SCHEDULER.enable ('myProg');
DBMS_SCHEDULER.create_job (
'myJob',
program_name => 'myProg',
comments => 'StartJob',
auto_drop => FALSE,
start_date => SYSTIMESTAMP,
event_condition => 'tab.user_data.event_name = ''give_me_a_prod''',
queue_spec => 'event_queue',
enabled => FALSE);
COMMIT;
END;
/
PROCEDURE enqueue(param1 IN PLS_INTEGER,
param2 IN PLS_INTEGER DEFAULT NULL,
param3 IN PLS_INTEGER DEFAULT NULL)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
l_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
l_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
l_message_handle RAW (16);
l_queue_msg t_event_queue_payload;
BEGIN
l_queue_msg := t_event_queue_payload ('give_me_a_prod');
-- Define arguments
DBMS_SCHEDULER.set_job_argument_value ('myJob', 1, TO_CHAR (param1));
DBMS_SCHEDULER.set_job_argument_value ('myJob', 2, TO_CHAR (param2));
DBMS_SCHEDULER.set_job_argument_value ('myJob', 3, TO_CHAR (param3));
DBMS_AQ.enqueue (queue_name => 'USERA.event_queue',
enqueue_options => l_enqueue_options,
message_properties => l_message_properties,
payload => l_queue_msg,
msgid => l_message_handle);
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
SQLERRM || ' - ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END enqueue;
包内:
PROCEDURE myProc(param1 IN PLS_INTEGER,
param2 IN PLS_INTEGER DEFAULT NULL,
param3 IN PLS_INTEGER DEFAULT NULL)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
...
PKG_SAP_FSCD_INTERRECIBOS.callSomething....
...
END myProc;
我已经创建了下一个程序和后续的 Oracle JOB:
BEGIN
DBMS_SCHEDULER.create_program (program_name => 'myProg',
program_action => 'myProc',
program_type => 'STORED_PROCEDURE',
number_of_arguments => 3,
enabled => FALSE);
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 1,
argument_type => 'NUMBER');
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 2,
argument_type => 'NUMBER');
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 3,
argument_type => 'NUMBER',
DEFAULT_VALUE => NULL);
DBMS_SCHEDULER.create_job ('myJob',
program_name => 'myProg',
enabled => FALSE,
comments => 'Send data');
DBMS_SCHEDULER.SET_ATTRIBUTE ('myJob', 'PARALLEL_INSTANCES', TRUE);
DBMS_SCHEDULER.SET_ATTRIBUTE ('myJob',
'logging_level',
DBMS_SCHEDULER.LOGGING_FULL);
END;
/
现在,我有一个用户可以 run/execute 调用下一个过程的作业:
PROCEDURE runJOB(param1 IN PLS_INTEGER,
param2 IN PLS_INTEGER DEFAULT NULL,
param3 IN PLS_INTEGER DEFAULT NULL)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
DBMS_SCHEDULER.enable ('myProg');
DBMS_SCHEDULER.set_job_argument_value ('myJob', 1, TO_CHAR (param1));
DBMS_SCHEDULER.set_job_argument_value ('myJob', 2, TO_CHAR (param2));
DBMS_SCHEDULER.set_job_argument_value ('myJob', 3, TO_CHAR (param3));
--DBMS_SCHEDULER.enable ('myJob');
DBMS_SCHEDULER.RUN_JOB (JOB_NAME => 'myJob', USE_CURRENT_SESSION => FALSE);
--DBMS_SCHEDULER.disable ('myJob');
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END runJOB;
我的问题是什么?
- 我需要 运行 异步模式下的作业。这就是为什么我有一个
enable
或run_job
使用USE_CURRENT_SESSION
参数FALSE
。我认为这可行。 - 我需要执行同一个作业的多个实例,首先
不同的用户,同时。例如,用户 A 调用
runJOB
程序。该作业可以在 20 秒内 运行。在这20 秒,用户 B 可以在不同的会话中调用相同的过程。 这就是我尝试使用PARALLEL_INSTANCES
属性的原因,但是 我只有一次执行。我认为 Oracle 认为这项工作是 运行ning,所以放弃第二次尝试运行。
在恢复中,我需要一个必须在异步模式下同时执行多个实例的作业。
在为两个实例执行作业 "double" 后,我只在 user_SCHEDULER_JOB_RUN_DETAILS
table 中获得一条记录,但是 2 为两个不同的用户(SGSS 和 EX01882_BD)
52367532 26/12/2016 12:08:44,584878 +00:00 SGSS myJob DEFAULT_JOB_CLASS RUN SUCCEEDED (HugeClob)
52364238 26/12/2016 12:08:36,529539 +00:00 SGSS myJob DEFAULT_JOB_CLASS ENABLE EX01882_BD (HUGECLOB)
52367534 26/12/2016 12:08:34,302807 +00:00 SGSS myJob DEFAULT_JOB_CLASS ENABLE SGSS (HUGECLOB)
有什么帮助吗?
注: 我不能使用与此解决方案 (How run two or more instances of an oracle job in the same time?) 中不同的作业名称,因为作业已经创建并且调用此作业的用户没有创建权限。
DBMS_SCHEDULER.RUN_JOB (JOB_NAME => 'myJob', USE_CURRENT_SESSION => FALSE);
现在,检查 documentation:
This specifies whether or not the job run should occur in the same session that the procedure was invoked from.
When use_current_session is set to TRUE:
The job runs as the user who called RUN_JOB, or in the case of a local external job with a credential, the user named in the
credential.You can test a job and see any possible errors on the command line.
run_count, last_start_date, last_run_duration, and failure_count are not updated.
RUN_JOB can be run in parallel with a regularly scheduled job run.
When use_current_session is set to FALSE:
The job runs as the user who is the job owner.
You need to check the job log to find error information.
run_count, last_start_date, last_run_duration, and failure_count are updated.
RUN_JOB fails if a regularly scheduled job is running.
解决方案:Event-Based Jobs
GRANT AQ_ADMINISTRATOR_ROLE TO USERA;
GRANT EXECUTE ON DBMS_SCHEDULER TO USERA;
GRANT EXECUTE ON sys.DBMS_SCHEDULER TO USERA;
GRANT EXECUTE ON sys.DBMS_ISCHED TO USERA;
GRANT CREATE JOB TO USERA;
GRANT CREATE EXTERNAL JOB TO USERA;
CREATE OR REPLACE TYPE t_event_queue_payload AS OBJECT (
event_name VARCHAR2(30)
);
BEGIN
-- Create a queue table to hold the event queue.
DBMS_AQADM.create_queue_table (
queue_table => 'event_queue_tab',
queue_payload_type => 't_event_queue_payload',
multiple_consumers => TRUE,
comment => 'Comments');
--Create the event queue.
DBMS_AQADM.create_queue (queue_name => 'event_queue',
queue_table => 'event_queue_tab');
-- Start the event queue.
DBMS_AQADM.start_queue (queue_name => 'event_queue');
END;
/
BEGIN
DBMS_SCHEDULER.create_program (
program_name => 'myProg',
program_action => 'USERA.PACKAGE.myProc',
program_type => 'STORED_PROCEDURE',
number_of_arguments => 3,
enabled => FALSE);
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 1,
argument_type => 'NUMBER');
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 2,
argument_type => 'NUMBER');
DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name => 'myProg',
argument_position => 3,
argument_type => 'NUMBER',
DEFAULT_VALUE => NULL);
DBMS_SCHEDULER.enable ('myProg');
DBMS_SCHEDULER.create_job (
'myJob',
program_name => 'myProg',
comments => 'StartJob',
auto_drop => FALSE,
start_date => SYSTIMESTAMP,
event_condition => 'tab.user_data.event_name = ''give_me_a_prod''',
queue_spec => 'event_queue',
enabled => FALSE);
COMMIT;
END;
/
PROCEDURE enqueue(param1 IN PLS_INTEGER,
param2 IN PLS_INTEGER DEFAULT NULL,
param3 IN PLS_INTEGER DEFAULT NULL)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
l_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
l_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
l_message_handle RAW (16);
l_queue_msg t_event_queue_payload;
BEGIN
l_queue_msg := t_event_queue_payload ('give_me_a_prod');
-- Define arguments
DBMS_SCHEDULER.set_job_argument_value ('myJob', 1, TO_CHAR (param1));
DBMS_SCHEDULER.set_job_argument_value ('myJob', 2, TO_CHAR (param2));
DBMS_SCHEDULER.set_job_argument_value ('myJob', 3, TO_CHAR (param3));
DBMS_AQ.enqueue (queue_name => 'USERA.event_queue',
enqueue_options => l_enqueue_options,
message_properties => l_message_properties,
payload => l_queue_msg,
msgid => l_message_handle);
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
SQLERRM || ' - ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END enqueue;
包内:
PROCEDURE myProc(param1 IN PLS_INTEGER,
param2 IN PLS_INTEGER DEFAULT NULL,
param3 IN PLS_INTEGER DEFAULT NULL)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
...
PKG_SAP_FSCD_INTERRECIBOS.callSomething....
...
END myProc;