Вопрос по SUBSCRIBER-у в AQ

-old-
Дата: 27.02.2007 18:02:05
Привет всем!
Изучая AQ наткнулся на понятие SUBSCRIBER. Принцип работы в документации описан гладко, но где его можно реально применить практически?! Вот вопрос. Не могли бы вы ткнуть в скрипт ?!-))
За что буду очень благодарен.
SQL*Plus
Дата: 27.02.2007 18:07:32
Subscriber - это подписчик, адресат, абонент...
Сообщение адресуется подписчику или группе подписчиков.
Пока все подписчики не заберут сообщение, оно из очереди не удаляется.

Что именно вам непонятно?

Спросите то же самое, но другими словами...
-old-
Дата: 27.02.2007 18:14:51
Да да. Вот такие фразы я уже читал
а нельзяли пример привести?
SQL*Plus
Дата: 27.02.2007 18:29:14
Oracle® Streams. Advanced Queuing User's Guide and Reference. 10g Release 2 (10.2). B14257-01. June 2005

Oracle Streams AQ Demonstrations
---------------------------------
Oracle Streams AQ demos can be installed from the Oracle Database Companion CD.
Once they are installed, you can find them in the $ORACLE_HOME/rdbms/demo
directory. Refer to aqxmlREADME.txt and aqjmsREADME.txt in the demo directory
for more information.

Table 1–1 lists and briefly describes the PL/SQL and OCI demos. Table 1–2 lists and
briefly describes the JMS demos. Table 1–3 lists and briefly describes the XML demos.

Прилагаемый архив содержит упоминаемые в таблицах файлы.
-old-
Дата: 27.02.2007 18:39:23
Вот в этих скриптах непонятен смысл скрипта

execute dbms_aqadm.add_subscriber ( -
queue_name => 'BZCARDORDERS_Q', -
subscriber => sys.aq$_agent('BILLING',null,null)-
);


Т.к.

declare
deqopt dbms_aq.dequeue_options_t;
mprop dbms_aq.message_properties_t;
msgid RAW(16);
payload bzcardorder_typ;
begin
deqopt.consumer_name := 'BILLING';
deqopt.navigation := DBMS_AQ.FIRST_MESSAGE;
deqopt.wait := 0;
dbms_aq.dequeue(
queue_name => 'bzcardorders_q',
dequeue_options => deqopt,
message_properties => mprop,
payload => payload,
msgid => msgid);

-- You can perform multiple database operations in the same transaction
-- You need not commit here Or you can use visibility immediate to commit

commit;
end;

отработает и без него! Проверял - работает!
SQL*Plus
Дата: 27.02.2007 18:48:09
-old-
Вот в этих скриптах непонятен смысл скрипта

execute dbms_aqadm.add_subscriber ( -
	  queue_name => 'BZCARDORDERS_Q', -
	  subscriber => sys.aq$_agent('BILLING',null,null)-
);

Т.к.
declare
	deqopt	dbms_aq.dequeue_options_t;
	mprop	dbms_aq.message_properties_t;
	msgid	RAW(16);
	payload bzcardorder_typ;
begin
	deqopt.consumer_name := 'BILLING';
	deqopt.navigation := DBMS_AQ.FIRST_MESSAGE;
	deqopt.wait := 0;	
	dbms_aq.dequeue(
		queue_name => 'bzcardorders_q',
		dequeue_options => deqopt,
		message_properties => mprop,
		payload => payload,
		msgid => msgid);

--	You can perform multiple database operations in the same transaction
-- 	You need not commit here Or you can use visibility immediate to commit

	commit;
end;
отработает и без него! Проверял - работает!
Что именно "отработает и без него! Проверял - работает!"???
Где фрагмент постановки сообщения в очередь?

Смысл выполнения
execute dbms_aqadm.add_subscriber ( -
	  queue_name => 'BZCARDORDERS_Q', -
	  subscriber => sys.aq$_agent('BILLING',null,null) );
в добавлении подписчика BILLING к очереди BZCARDORDERS_Q
fbp2004
Дата: 27.02.2007 21:18:28
Вот здесь

declare
	enqopt	dbms_aq.enqueue_options_t;
	mprop	dbms_aq.message_properties_t;
	enq_msgid	RAW(16);
	rcpt_list dbms_aq.aq$_recipient_list_t;
begin
	rcpt_list(0) := sys.aq$_agent('Billing', null, null);
	rcpt_list(1) := sys.aq$_agent('Shipping', null, null);
	mprop.recipient_list := rcpt_list;
	dbms_aq.enqueue(
		queue_name => 'bzcardorders_q',
		enqueue_options => enqopt,
		message_properties => mprop,
		payload => bzcardorder_typ(101, 'Brajesh', 'Goyal','NORMAL'),
		msgid => enq_msgid);

--	You can perform multiple database operations in the same transaction
-- 	You need not commit here Or you can use visibility immediate to commit

	commit;
end;
-old-
Дата: 27.02.2007 22:19:33
Сори! Предыдущее сообщение было моё.-)
prokop
Дата: 28.02.2007 10:11:59
Просто нужно различать subscriber и recipient
dbms_aqadm.add_subscriber - создает подписчика для очереди.
Если при постановке сообщения указывает список получателей (recipient_list) то сообщение будет направлено только им.
-- Создаем таблицу очередей и очередь
SQL> BEGIN
  2   dbms_aqadm.create_queue_table(queue_table => 'TQ1',
  3                                 queue_payload_type => 'RAW',
  4                                 multiple_consumers => TRUE);
  5   dbms_aqadm.create_queue(queue_name => 'Q1',
  6                           queue_table => 'TQ1');                                
  7   dbms_aqadm.start_queue('Q1',TRUE,TRUE);                         
  8  END;
  9  /

PL/SQL procedure successfully completed.
-- Пытаемся поставить в очередь сообщение без указания получателя.
-- Ожидаемый результат - ошибка
SQL> DECLARE
  2   l_enq dbms_aq.enqueue_options_t;
  3   l_mp  dbms_aq.message_properties_t;
  4   l_msgid RAW(16);
  5  begin
  6    dbms_aq.enqueue(queue_name => 'Q1',
  7                   enqueue_options => l_enq,
  8                   message_properties => l_mp,
  9                   payload => utl_raw.cast_to_raw('No subscribers'),
 10                   msgid => l_msgid);
 11  END;
 12  /
DECLARE
*
ERROR at line 1:
ORA-24033: no recipients for message
ORA-06512: at "SYS.DBMS_AQ", line 6
ORA-06512: at "SYS.DBMS_AQ", line 216
ORA-06512: at line 6

-- Ставим в очередь сообщение для получателя Billing

SQL> DECLARE
  2   l_enq dbms_aq.enqueue_options_t;
  3   l_mp  dbms_aq.message_properties_t;
  4   l_msgid RAW(16);
  5   rcpt_list dbms_aq.aq$_recipient_list_t;
  6  begin
  7   rcpt_list(1) := sys.aq$_agent('Billing', null, null);
  8    l_mp.recipient_list  := rcpt_list;
  9    dbms_aq.enqueue(queue_name => 'Q1',
 10                   enqueue_options => l_enq,
 11                   message_properties => l_mp,
 12                   payload => utl_raw.cast_to_raw('For Billing'),
 13                   msgid => l_msgid);
 14  END;
 15  /

PL/SQL procedure successfully completed.

SQL> COMMIT
  2  /

Commit complete.

SQL> SELECT queue, consumer_name, utl_raw.cast_to_varchar2(user_data) data  FROM AQ$TQ1
  2  /

QUEUE                CONSUMER_NAME        DATA
-------------------- -------------------- ------------------------------
Q1                   BILLING              For Billing

-- Дабавляем подписчика по умолчанию для очереди
SQL> begin
  2   dbms_aqadm.add_subscriber(queue_name => 'Q1',subscriber => SYS.AQ$_AGENT('Subscriber',NULL,NUL
L));
  3  end;
  4  /

PL/SQL procedure successfully completed.

-- Ставим в очередь сообщение без явного указания получателей
-- Ожидаемый результат - сообщение будет поставлено только для подписчиков по умолчанию

SQL> DECLARE
  2   l_enq dbms_aq.enqueue_options_t;
  3   l_mp  dbms_aq.message_properties_t;
  4   l_msgid RAW(16);
  5  begin
  6    dbms_aq.enqueue(queue_name => 'Q1',
  7                   enqueue_options => l_enq,
  8                   message_properties => l_mp,
  9                   payload => utl_raw.cast_to_raw('For Subscriber'),
 10                   msgid => l_msgid);
 11  END;
 12  /

PL/SQL procedure successfully completed.

SQL> commit
  2  /

Commit complete.

SQL>  SELECT queue, consumer_name, utl_raw.cast_to_varchar2(user_data) data  FROM AQ$TQ1
  2  /

QUEUE                CONSUMER_NAME        DATA
-------------------- -------------------- ------------------------------
Q1                   BILLING              For Billing
Q1                   SUBSCRIBER           For Subscriber

-- Ставим в очередь сообщение для Billing и Subscriber
-- Ожидаемый результат - сообщение будет поставлено для Billing и Subscriber


SQL> DECLARE
  2   l_enq dbms_aq.enqueue_options_t;
  3   l_mp  dbms_aq.message_properties_t;
  4   l_msgid RAW(16);
  5   rcpt_list dbms_aq.aq$_recipient_list_t;
  6  begin
  7   rcpt_list(1) := sys.aq$_agent('Billing', null, null);
  8   rcpt_list(2) := sys.aq$_agent('Subscriber', null, null);  
  9    l_mp.recipient_list  := rcpt_list;
 10    dbms_aq.enqueue(queue_name => 'Q1',
 11                   enqueue_options => l_enq,
 12                   message_properties => l_mp,
 13                   payload => utl_raw.cast_to_raw('For Subscriber and Billing'),
 14                   msgid => l_msgid);
 15  END;
 16  /

PL/SQL procedure successfully completed.

SQL> SELECT queue, consumer_name, utl_raw.cast_to_varchar2(user_data) data  FROM AQ$TQ1
  2  /

QUEUE                CONSUMER_NAME        DATA
-------------------- -------------------- ------------------------------
Q1                   BILLING              For Billing
Q1                   SUBSCRIBER           For Subscriber
Q1                   BILLING              For Subscriber Billing
Q1                   SUBSCRIBER           For Subscriber Billing
-old-
Дата: 28.02.2007 10:27:28
Кажется понял -)) Да на самом деле сообщение можно поставить в очередь
без адресата. И если на эту очередь был назначен subscriber, то он его перехватит.
Я правильно понял ?)