oracle高级队列介绍
高级队列Advanced Queuing(AQ)在oracle多个版本都可得到。他是oracle原生消息软件并且在每一个版本都在加强。
这篇文章提供了一个AQ的高级概览。尤其是我们将看到如何启动一个队列并进行入列--出列操作,还有通过通知创建异步出列。
注意AQ支持
数据库意外的消息监听(例如JMS消息队列)。本文仅涉及数据库内部消息通信。
要求:
本例要求指定的角色和权限(除了标准CREATE SESSION/TABLE/PROCEDURE/TYPE和表空间配额外)
1、AQ_ADMINISTRATOR_ROLE: 用于创建队列表和队列;
2、EXECUTE ON DBMS_AQ:用于通知案例中启用PLSQL存储过程编译
另外,需要入列/出列消息的标准应用用户要求AQ权限通过DBMS_AQADM[GRANT|REVOKE]_QUEUE_PRIVILIEGE API提供。
以下例子可以运行在任何拥有以上权限的用户下。
1、创建并启动一个队列
AQ处理的消息称为"有效负荷"(payloads) 。消息格式可以是用户自定义对象或XMLType或ANYDATA。当我们创建一个队列,需要告诉oracle
有效负荷的结构,所以我们先创建一个简单对象类型。
CREATE TYPE demo_queue_payload_type AS OBJECT
( message VARCHAR2(4000) );
/
我们有效负荷类型包含一个属性,而现实中可能更复杂。下面创建队列表用于存储队列消息直到永久出列。
BEGIN
DBMS_AQADM.CREATE_QUEUE_TABLE (
queue_table => 'demo_queue_table',
queue_payload_type => 'demo_queue_payload_type'
);
END;
/
接着创建队列并启动:
BEGIN
DBMS_AQADM.CREATE_QUEUE (
queue_name => 'demo_queue',
queue_table => 'demo_queue_table'
);
DBMS_AQADM.START_QUEUE (
queue_name => 'demo_queue'
);
END;
/
至此,我们已经创建了队列有效负荷,队列表和队列。来看下有哪些相关对象:
SELECT object_name, object_type
FROM user_objects
WHERE object_name != 'DEMO_QUEUE_PAYLOAD_TYPE';
OBJECT_NAME OBJECT_TYPE
------------------------------ ---------------
DEMO_QUEUE_TABLE TABLE
SYS_C009392 INDEX
SYS_LOB0000060502C00030$$ LOB
AQ$_DEMO_QUEUE_TABLE_T INDEX
AQ$_DEMO_QUEUE_TABLE_I INDEX
AQ$_DEMO_QUEUE_TABLE_E QUEUE
AQ$DEMO_QUEUE_TABLE VIEW
DEMO_QUEUE QUEUE
我们看到一个队列带出了一系列自动生成对象,有些是被后面直接用到的。不过有趣的是,创建了第二个队列。这就是所谓的异常队列(exception
queue)。如果AQ无法从我们的队列接收消息,将记录在该异常队列中。
2、入列消息(enqueuing messages)
我们已经准备好使用DBMS_AQ.ENQUEUE API去入列一个消息。接下来的例子,我们使用ENQUEUE过程入列一个单条消息。
DBMS_AQ有大范围的记录和数组类型来支持其接口并使我们去修改其行为(我们将在下面的例子看到2个此类引用)。
DECLARE
r_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
r_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
v_message_handle RAW(16);
o_payload demo_queue_payload_type;
BEGIN
o_payload := demo_queue_payload_type('Here is a message');
DBMS_AQ.ENQUEUE(
queue_name => 'demo_queue',
enqueue_options => r_enqueue_options,
message_properties => r_message_properties,
payload => o_payload,
msgid => v_message_handle
);
COMMIT;
END;
/
可以看到入列消息很简单。入列操作是一个基本的事务(就像往队列表Insert),因此我们需要提交。
3、浏览消息(browsing messages)
在我们出列消息之前,我们将"浏览"队列内容。首先我们可以查询AQ$DEMO_QUEUE_TABLE视图看到多少消息已经入列。正如我们早些看到的,
该视图是在前面DBMS_AQADM.CREATE_QUEUE创建队列自动生成的。
SELECT COUNT(*)
FROM aq$demo_queue_table;
COUNT(*)
----------
1
和我们预期一样,队列中只有一条消息。我们有2种方法可以浏览消息内容:
1)直接查询视图:
SELECT user_data
FROM aq$demo_queue_table;
USER_DATA(MESSAGE)
------------------------------------------------------------
DEMO_QUEUE_PAYLOAD_TYPE('Here is a message')
2)我们可以使用DBMS_AQ.DEQUEUE API浏览。根据名字可以看出,该过程用于出列消息。为了达到只浏览不删除的目的,我们可以使用
DBMS_AQ.BROWSE修改出列属性(默认是DBMS_AQ.REMOVE)。
DECLARE
r_dequeue_options DBMS_AQ.DEQUEUE_OPTIONS_T;
r_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
v_message_handle RAW(16);
o_payload demo_queue_payload_type;
BEGIN
r_dequeue_options.dequeue_mode := DBMS_AQ.BROWSE;
DBMS_AQ.DEQUEUE(
queue_name => 'demo_q