首页 > 解决方案 > Oracle AQ 传播 - 与接收者合作的秘诀

问题描述

各自所有!

最后,我让它工作了。我的意思是使用 recipents list 进行传播,在调用dbms_aq.enqueue时在message_properties参数中明确指定 所以,我们有什么:

环境

源队列表:

begin
  sys.dbms_aqadm.create_queue_table(
    queue_table => 'STERN.RADIO',
    queue_payload_type => 'RAW',
    sort_list => 'ENQ_TIME',
    multiple_consumers => TRUE,
    compatible => '10.0.0',
    primary_instance => 0,
    secondary_instance => 0,
    storage_clause => 'tablespace USERS pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K next 1M minextents 1 maxextents unlimited )');
end;

源队列:

begin
  sys.dbms_aqadm.create_queue(
    queue_name => 'STERN.RADIO_Q',
    queue_table => 'STERN.RADIO',
    queue_type => sys.dbms_aqadm.normal_queue,
    max_retries => 5,
    retry_delay => 0,
    retention_time => 0);
end;

目标队列表:

begin
  sys.dbms_aqadm.create_queue_table(
    queue_table => 'STERN1.RECEIVER',
    queue_payload_type => 'RAW',
    sort_list => 'ENQ_TIME',
    multiple_consumers => TRUE,
    compatible => '10.0.0',
    primary_instance => 0,
    secondary_instance => 0,
    storage_clause => 'tablespace USERS pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K next 1M minextents 1 maxextents unlimited )');
end;

目标队列:

begin
  sys.dbms_aqadm.create_queue(
    queue_name => 'STERN1.RECEIVER_Q',
    queue_table => 'STERN1.RECEIVER',
    queue_type => sys.dbms_aqadm.normal_queue,
    max_retries => 5,
    retry_delay => 0,
    retention_time => 0);
end;

源队列的订阅者:

begin
  dbms_aqadm.add_subscriber(queue_name => 'STERN.RADIO_Q', 
  subscriber => sys.aq$_agent(null,'STERN1.RECEIVER_Q',null),
  queue_to_queue => true,delivery_mode =>  dbms_aqadm.PERSISTENT);
end;  

请注意:订阅者的名称为 NULL。源队列的传播工作:

begin
  dbms_aqadm.schedule_propagation(queue_name => 'STERN.RADIO_Q',
  destination => null,destination_queue => 'STERN1.RECEIVER_Q');
end; 

传播作业的目标只是一个队列。

目标队列有一个订阅者(至少应该存在一个,否则作业将失败):

begin
  dbms_aqadm.add_subscriber(queue_name => 'STERN1.RECEIVER_Q',
  subscriber => sys.aq$_agent('kulik',null,null));
end; 

当 enqueue 块中没有收件人时,一切正常:

declare 
 v$opt dbms_aq.enqueue_options_t;
 v$prop dbms_aq.message_properties_t;
 v$mid raw(16); 
 v$send raw(16) := utl_raw.cast_to_raw('Gromozeka 1');
begin
  dbms_aq.enqueue(queue_name => 'STERN.RADIO_Q',
    enqueue_options =>  v$opt,
    message_properties => v$prop,
    payload => v$send,msgid => v$mid);
   commit;
end; 

如果有一个收件人,按照 Oracle 文档中指定的格式形成,则作业找不到目的地并永远挂起......

declare 
 v$opt dbms_aq.enqueue_options_t;
 v$prop dbms_aq.message_properties_t;
 v$mid raw(16); 
 v$send raw(16) := utl_raw.cast_to_raw('Gromozeka 1');
 recipients DBMS_AQ.aq$_recipient_list_t;
begin
    recipients(1) := sys.aq$_agent(null,
      'STERN1.RECEIVER_Q',null); 
  v$prop.recipient_list := recipients; 
  
  dbms_aq.enqueue(queue_name => 'STERN.RADIO_Q',
    enqueue_options =>  v$opt,
    message_properties => v$prop,
    payload => v$send,msgid => v$mid);
   commit;
end;       

如果有收件人,按照 Oracle 文档中未指定的方式形成,一切正常!

declare 
 v$opt dbms_aq.enqueue_options_t;
 v$prop dbms_aq.message_properties_t;
 v$mid raw(16); 
 v$send raw(16) := utl_raw.cast_to_raw('Gromozeka 1');
 recipients DBMS_AQ.aq$_recipient_list_t;
begin
  recipients(1) := sys.aq$_agent(null,
      '"STERN"."RADIO_Q":"STERN1"."RECEIVER_Q"',null); 
  v$prop.recipient_list := recipients; 
  
  dbms_aq.enqueue(queue_name => 'STERN.RADIO_Q',
    enqueue_options =>  v$opt,
    message_properties => v$prop,
    payload => v$send,msgid => v$mid);
   commit;
end; 

希望这可以帮助。问候,安德鲁。

标签: oraclequeuepropagationqueueing

解决方案


推荐阅读