【问题标题】:Oracle Advance Queue Dequeue callback not workingOracle Advance Queue Dequeue 回调不起作用
【发布时间】:2020-01-28 15:52:16
【问题描述】:

我有 2 个架构:(A 和 B) 在模式 A 中,我创建了提前队列和出队回调函数。 从模式 A 我授予模式 B 执行入队过程。 当我从模式 A 中排队数据时 -> 一切正常。 当我从模式 B 调用 A.enqueue 数据过程时 -> 数据已入队,但它们仍处于 READY 状态...。出队回调函数未触发。这是测试脚本:

我有用户 A

create table test_table (id number, event_name varchar2(200), descr nvarchar2(200));  
/  
create or replace type test_type as object (id number, event_name varchar2(200), descr nvarchar2(200))  
/  
create or replace procedure test_proc(context  in raw,  
                                      reginfo  in sys.aq$_reg_info,  
                                      descr    in sys.aq$_descriptor,  
                                      payload  in raw,  
                                      payloadl in number) as  
  v_dequeue_options    dbms_aq.dequeue_options_t;  
  v_message_id         raw(16);  
  v_payload_message    test_type;  
  v_message_properties dbms_aq.message_properties_t;  
begin  
  v_dequeue_options.msgid         := descr.msg_id;  
  v_dequeue_options.consumer_name := descr.consumer_name;  
  v_dequeue_options.wait          := dbms_aq.no_wait;  
  DBMS_AQ.DEQUEUE(queue_name         => 'event_queue',  
                  dequeue_options    => v_dequeue_options,  
                  message_properties => v_message_properties,  
                  payload            => v_payload_message,  
                  msgid              => v_message_id);  


  insert into test_table  
    (id, event_name, descr)  
  values  
    (v_payload_message.id, v_payload_message.event_name, v_payload_message.descr);  


  commit;  
end;  
/  
create or replace procedure enq_data(p_msg in varchar2) is  
  l_enqueue_options    DBMS_AQ.enqueue_options_t;  
  l_message_properties DBMS_AQ.message_properties_t;  
  l_message_handle     raw(16);  
  l_event_msg          test_type;  
begin  
  l_event_msg := test_type(2, p_msg, null);  
  DBMS_AQ.enqueue(queue_name         => 'cp.event_queue',  
                  enqueue_options    => l_enqueue_options,  
                  message_properties => l_message_properties,  
                  payload            => l_event_msg,  
                  msgid              => l_message_handle);  


  commit;  
end;  
/  
begin  
 DBMS_AQADM.create_queue_table(    
   queue_table        =>  'event_queue_tab',   
    --sort_list => 'COMMIT_TIME',  
    multiple_consumers => false,  
    message_grouping => sys.dbms_aqadm.none,  
    compatible => '10.0.0',  
    primary_instance => 0,    
    secondary_instance => 0,  
    queue_payload_type =>  'test_type');   


  DBMS_AQADM.create_queue(    
   queue_name         =>  'event_queue',    
   queue_table        =>  'event_queue_tab');  


  DBMS_AQADM.start_queue(    
   queue_name         => 'event_queue',    
   enqueue            => TRUE);  
end;  
/  
begin  
  dbms_aq.register (  
     sys.aq$_reg_info_list (  
        sys.aq$_reg_info (user || '.' || upper('event_queue'),  
                          dbms_aq.namespace_aq,  
                          'plsql://' || user || '.test_proc',  
                          hextoraw ('FF'))),  
     1);  
  commit;  
end;  
/  


grant execute on enq_data to B;  
grant select on test_table to B;  


connect with user A

---- THIS PART IS FOR TESTING  
DECLARE  
BEGIN  
  enq_data('sdadasd');  
END;  
/  
select * from test_table;  


connect with user B

---- THIS PART IS FOR TESTING  
DECLARE  
BEGIN  
  A.enq_data('sdadasd');  
END;  
/  
select * from A.test_table;  

我看到记录处于就绪状态:

从 aq$event_queue_tab 中选择 *;

为什么……我做错了什么?

【问题讨论】:

  • 首先,您的 enq_data proc 上面的队列名称有错误(删除“cp.”)。然后我用这个更正尝试了你的代码,它可以工作,我看到 test_table 中的行
  • sry,那个 CP 是我的模式名称......忘记删除测试用例......所有排队的消息都处于 READY 状态......我不知道为什么没有触发回调函数.

标签: oracle advanced-queuing


【解决方案1】:

文档说sys.aq$_reg_info_list(回调)中的第三个字段应该是 喜欢plsql://schema.procedure?PR=1

所以,试试

  dbms_aq.register (  
     sys.aq$_reg_info_list (  
        sys.aq$_reg_info (user || '.' || upper('event_queue'),  
                          dbms_aq.namespace_aq,  
                          'plsql://' || user || '.test_proc?PR=1',  
                          hextoraw ('FF'))),  
     1); 

然后,Oracle 需要后台作业才能使回调工作。 所以检查系统参数job_queue_processesaq_tm_processes

【讨论】:

    猜你喜欢
    • 2019-07-19
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多