我有两个过程p1和p2,前者打印1到10,后者打印10到1,我使用调度程序并行运行这两个过程。我的代码是
BEGIN
dbms_scheduler.create_job (
job_name => 'j1a',
job_type => 'STORED_PROCEDURE',
job_action => 'p1',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=DAILY', /* every day */
enabled => TRUE
);
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'j2a',
job_type => 'STORED_PROCEDURE',
job_action => 'p2',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=DAILY' ,/* every other day */
enabled => TRUE
);
end;
BEGIN
DBMS_SCHEDULER.RUN_JOB(
JOB_NAME => 'j1a,j2a'
--USE_CURRENT_SESSION => FALSE
);
end;我得到的输出结果是
1
2
3
4
5
6
7
8
9
10
10
9
8
7但不是像
1
2
10
9
8
3
..请在这方面帮助我。
发布于 2020-01-04 23:48:02
您运行的作业如下所示:
DBMS_SCHEDULER.RUN_JOB(
JOB_NAME => 'j1a,j2a'
--USE_CURRENT_SESSION => FALSE
);USE_CURRENT_SESSION的默认值为true。这意味着这两个作业在同一会话中运行,这意味着它们以串行方式以方式运行。没有办法改变这种行为:一个会话一次只能运行一个作业。
您可以通过取消注释USE_CURRENT_SESSION参数设置来并行运行这些作业,但是这样您就不会在会话中看到输出。但是,有一个选项:使用DBMS_PIPE。DBMS_PIPE是一个Oracle内置库,它允许会话相互通信。在这种情况下,您可以使用它将消息从后台作业发送到另一个会话,该会话将接收消息并将其写入DBMS_OUTPUT缓冲区。
下面的代码可能看起来有点过分满足您的需求,但自从我上次使用DBMS_PIPE以来已经有十多年了,生锈的管道对健康有害,所以我们开始吧!
这是一个玩具信息管装。它有两个过程-一个用于发送消息,另一个用于读取消息:
create or replace package messaging is
subtype t_message is varchar2(128);
c_pipe_name constant varchar2(30) := 'MSG_PIPE';
c_stop constant t_message := 'STOP';
procedure listen (p_timeout in number default null);
procedure send (p_message in t_message);
end messaging;
/简单地说,监听过程保持打开,直到任何发送者通知它停止为止。下面是包的实现:
create or replace package body messaging is
procedure listen (p_timeout in number default null) is
l_timeout pls_integer;
l_message t_message := 'waiting';
l_status pls_integer;
begin
dbms_output.put_line(c_pipe_name || ' listening');
l_status := DBMS_PIPE.create_pipe(pipename => c_pipe_name
, private => false);
l_timeout := coalesce(p_timeout, DBMS_PIPE.maxwait);
while l_message != c_stop loop
l_status := DBMS_PIPE.receive_message(pipename => c_pipe_name
, timeout => l_timeout);
if l_status = 0 then
DBMS_PIPE.unpack_message(l_message);
dbms_output.put_line('Message received: ' || l_message);
end if;
end loop;
l_status := DBMS_PIPE.remove_pipe(pipename => c_pipe_name);
dbms_output.put_line(c_pipe_name || ' stopped');
end listen;
procedure send (p_message in t_message) is
l_status number;
begin
DBMS_PIPE.pack_message(p_message);
l_status := DBMS_PIPE.send_message(c_pipe_name);
end send;
end messaging;
/我已经重写了您的存储过程来调用messaging.send():
create or replace procedure p1 is
l_message varchar2(80) := 'P#1:';
begin
for idx in 1..10 loop
messaging.send(l_message || to_char(idx));
dbms_session.sleep(1);
end loop;
messaging.send(messaging.c_stop);
end;
/
create or replace procedure p2 is
l_message varchar2(80) := 'P#2:';
begin
for idx in reverse 1..10 loop
messaging.send(l_message || to_char(idx));
dbms_session.sleep(1);
end loop;
messaging.send(messaging.c_stop);
end;
/这些例程使用sleep(),因为我手动运行它们进行测试,并且必须确保第一个例程在我启动第二个例程之前没有完成:当它们作为作业运行时,您可能不需要它们。(顺便说一句,我使用了期待已久的Robertson增强DBMS_SESSION.SLEEP(),因为我运行的是Oracle18c;如果您使用的是较早的版本,则可能需要要求数据库管理员授予您在DBMS_LOCK上执行或不休眠执行的权限。)
为了确保您的作业提交代码的完整性:
BEGIN
dbms_scheduler.create_job (
job_name => 'j1a',
job_type => 'STORED_PROCEDURE',
job_action => 'p1',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=DAILY', /* every day */
enabled => TRUE
);
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'j2a',
job_type => 'STORED_PROCEDURE',
job_action => 'p2',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=DAILY' ,/* every other day */
enabled => TRUE
);
end;
/现在,我设置了一个会话来监听消息...
begin
messaging.listen();
end;
/..。在另一个会话中,我启动您的作业在后台运行:
BEGIN
DBMS_SCHEDULER.RUN_JOB(
JOB_NAME => 'j1a,j2a'
, USE_CURRENT_SESSION => FALSE
);
end;
/看哪!下面是dbms_output:
MSG_PIPE listening
Message received: P#1:1
Message received: P#2:10
Message received: P#2:9
Message received: P#1:2
Message received: P#2:8
Message received: P#1:3
Message received: P#2:7
Message received: P#1:4
Message received: P#1:5
Message received: P#2:6
Message received: P#2:5
Message received: P#1:6
Message received: P#1:7
Message received: P#2:4
Message received: P#2:3
Message received: P#1:8
Message received: P#1:9
Message received: P#2:2
Message received: P#2:1
Message received: P#1:10
Message received: STOP
MSG_PIPE stopped因此,很明显,这些过程是并行运行的,但消息并没有整齐地交错。当我们运行自主并行作业时,这是不可避免的,而会话之间没有任何交互作用。
https://stackoverflow.com/questions/59588772
复制相似问题