Sql 在触发器中使用DBMS_PIPE.PACK_消息和DBMS_PIPE.SEND_消息

Sql 在触发器中使用DBMS_PIPE.PACK_消息和DBMS_PIPE.SEND_消息,sql,oracle,plsql,oracle12c,Sql,Oracle,Plsql,Oracle12c,环境:甲骨文12c 我正在考虑在许多用户将使用的表触发器中使用Oracle DBMS_管道。触发器仅在状态更新时触发,如下所示: CREATE OR REPLACE TRIGGER MY_TRG AFTER UPDATE OF STATUS ON "MY_TABLE" REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW declare v_status INTEGER; begin if :OLD.

环境:甲骨文12c

我正在考虑在许多用户将使用的表触发器中使用Oracle DBMS_管道。触发器仅在状态更新时触发,如下所示:

CREATE OR REPLACE TRIGGER MY_TRG  
AFTER UPDATE OF STATUS ON "MY_TABLE"  
REFERENCING NEW AS NEW OLD AS OLD  
FOR EACH ROW  
declare  
   v_status    INTEGER;  
begin      
    if :OLD.status = 'ERROR' and (:NEW.status = 'OK' or :NEW.status = 'ERROR') then  
       DBMS_PIPE.PACK_MESSAGE(:OLD.id_key);  
       DBMS_PIPE.PACK_MESSAGE(:NEW.status);  

       v_status := DBMS_PIPE.SEND_MESSAGE('MY_PIPE');  

       if v_status != 0 THEN  
         raise_application_error(num => -20002,msg => 'error message on trigger!');  
      end if;  
    end if;
  end;  
以下调用将从Oracle APEX页面进程启动,在该进程中,多个用户可以再次提交

DBMS_PIPE.receive_message(pipename => 'MY_PIPE', timeout  => 10);   
我的问题是,对于这里的每个用户,我是否需要确保管道名称特定于每个用户,以便他们只能在管道中看到他们的消息,或者仅“My_PIPE”管道名称就可以处理多个用户的所有事务

如果每个用户都需要自己指定的管道名称,如果
SEND\u MESSAGE('user\u 1\u PIPE')
是从表触发器触发的,我的receive\u MESSAGE\u proc将不知道这个“user\u 1\u PIPE”名称,我该如何做

我的“创建管道”如下所示:

v_res := DBMS_PIPE.create_pipe(pipename => 'MY_PIPE', private => TRUE);  

我假设我需要用每个用户自己的私有管道名称标记每个用户-这是否正确?

私有管道是私有的,即创建它们的用户名。如果有多个人使用同一用户帐户登录,那么他们都将能够看到该管道

但也许更大的问题是管道不是事务性的。因此,一旦触发,消息就会被放入管道中……即使该事务稍后回滚,或失败,或其他任何不会最终更新状态的情况。此外,管道消息将在事务提交之前发送。在提交发生之前,另一个会话(接收该管道消息)将无法看到所做的更改,这可能导致时间不一致

也许AQ(高级队列)是一个您可能需要考虑的替代方案。默认情况下,队列上的消息是事务性的,因此队列上的消息将很好地绑定到您对状态的更改是否实际成功


调用应用程序只侦听队列而不是管道消息。

这似乎取决于管道的类型。你能给我们看一下
CREATE PIPE
声明吗?@wolφ我更新了我的帖子以反映你的问题。嗨,康纳-感谢你的回复。实际上,我已经开始研究AQs,并为此创建了一个新的SO线程-请参见此处:。如果你能在这个帖子上举个例子看看如何使用AQ方法,我将不胜感激。非常感谢。我决定在DBMS_管道上使用Oracle高级队列方法。