《OracleAQ消息队列的使用详解》由会员分享,可在线阅读,更多相关《OracleAQ消息队列的使用详解(7页珍藏版)》请在金锄头文库上搜索。
1、Oracle AQ 消息队列()随着不同应用模块间的消息交互和通信成为一个关键的功能,并且变得越来越重要。Oracle 引入了一种强大的队列机制,通过它程序间可以实现信息的交互,oracle 把它称作为 AQ - Advanced Queuing. 使用 Oracle AQ,我们不需要安装额外的中间件,它是Oracle 数据库的一个功能组件,只要你安装了 Oracle 数据库就可以使用 AQ 了。接下来分两部分来介绍 AQ 的使用,使用之前我们要创建 QUEUE.我们创建一个自己的 AQ 的管理角色 my_aq_adm_role 和管理用户aqadm,再把Oracle AQ 管理角色 aq_a
2、dminstrator_role 授权给my_aq_adm_role.CREATE ROLE my_aq_adm_role;GRANT aq_adminsistator_role TO my_aq_adm_role创建一个用户的角色 my_aq_user_role 和 普通用户aquser ,再把 Oracle AQ 的用户角色aq_user_role和一些基本操作需要的系统权限授权给 my_aq_adm_roleCREATE ROLE my_aq_user_role;GRANT CREATE session, aq_user_role TO my_aq_user_role;EXEC DBMS
3、_AQADM.GRANT_SYSTEM_PRIVILEGE(privilege = ENQUEUE_ANY,grantee = my_aq_user_role,admin_option = FALSE);EXEC DBMS_AQADM.GRANT_SYSTEM_PRIVILEGE(privilege = DEQUEUE_ANY,grantee = my_aq_user_role,admin_option = FALSE);现在我们创建 AQ 管理用户CREATE USER aqadm IDENTIFIED BY aqadmDEFAULT TABLESPACE elathenTEMPORARY
4、TABLESPACE temp;GRANT my_aq_adm_role TO aqadm;GRANT connect, resource TO aqadm; -注意,resource 角色一定要授给 user,如果resource 角色授权给my_aq_adm_role, user 将会失去 unlimited tablespace 权限接着为我们下面 example 创建普通用户CREATE USER aquser IDENTIFIED BY aquserDEFAULET TABLESPACE elathenTEMPORARY TABLESPACE temp;GRANT my_aq_use
5、r_role TO aquser;我们将在我们第一个 queue 中使用 object type 而不是 NUMBER or VARCHAR2 作为payload,这使我们更贴近实际应用。(payload 是任何消息都使用的一种数据类型和结构 ). 上面做的工作都需要在 DBA 的权限下做,现在我们切换到 AQ 管理员CONNECT aqadm/aqadmCREATE TYPE queue_message_type AS OBJECT(no NUBER,title VARCHAR2(30),text VARCHAR2(2000);/GRANT EXECUTE ON queue_message_
6、type TO my_aq_user_role;我们再创建一个叫message_queue的 queue 以及相应的 queue table queue_message_table,然后启动 queue,这样我们就可以使用了。1.PL/SQL 中使用 AQ 和 java 使用 oracle 本地 AQ点对点模型(The Point-to-point Model)在简单的系统中,我们可以认为两个系统一起使用一个或多个 Queue。这种方法我们称作点对点模型。把消息输入到 queue 中的过程称为入列(Enqueue)相反的过程称为出列(Dequeue)。一条消息一次只能被一个使用这个 queue
7、 的应用系统 Dequeue,当其他应用系统可以浏览这个 queue。这种模式就是点对点模式(the point-point Model)PL/SQL 中使用 AQ使用 aquser 连接到数据库CONNECT aquser/aquser现在我们 Enqueue 一条消息.DECLAREqueue_optionsDBMS_AQ.enqueue_options_t;message_properties DBMS_AQ.message_properties_t;message_idRAW(16);my_messageaqadm.queue_message_type;BEGINmy_message
8、:= aqadm.queue_message_type(1,This is a sample message,This message has been posted on | to_char(SYSDATE,DD.MM.YYYY HH24:MI:SS);DBMS_AQ.enqueue(queue_name = aqadm.message_queue,enqueue_options = queue_options,message_properties = message_properties,payload = my_message,msgid = message_id);COMMIT;END
9、;/我们现在 Dequeue 刚才入列的消息,先执行SET SERVEROUTPUT ON然后DECLAREqueue_options DBMS_AQ.DEQUEUE_OPTIONS_T;message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;message_id RAW(2000);my_message aqadm.queue_message_type;BEGINDBMS_AQ.DEQUEUE(queue_name = aqadm.message_queue,dequeue_options = queue_options,message_propert
10、ies = message_properties,payload = my_message,msgid = message_id );COMMIT;DBMS_OUTPUT.PUT_LINE(Dequeued no: | my_message.no);DBMS_OUTPUT.PUT_LINE(Dequeued title: | my_message.title);DBMS_OUTPUT.PUT_LINE(Dequeued text: | my_message.text);END;/上面的 PL/SQL 的例子比较简单和直接,任何应用和编程环境都可以这样做。然而实际项目中,可能用编程语言来处理消息
11、会更便利和更有实用价值。接下来我们将讨论在 java 中使用 AQJava 中使用 Oracle Native AQ在前面的例子里我们为队列消息创建了一个 Oracle Object type queue_message_type,在 java 语言中我们不能使用 Oracle 的数据类型,因此我们要创建一个和queue_message_type对应的 java 类。我们可以使用 Oracle Jpublisher,通过它,我们可以创建一个和 Oracle Object type 对应的 java 类。(这里就不具体讨论 JPublisher 用法)这里我们用 JPubisher 创建一个和
12、Oracle Object type queue_message_type对应 java class QUEUE_MESSAGE_TYPE 在使用 Oracle Native AQ 对 java 的 interface 之前,我们必须通过 jdbc 连接到数据库,代码如下/loads the Oracle JDBC driverClass.forName(oracle.jdbc.driver.OracleDriver ;NativeAQ aq = new NativeAQ();/DB connection, HOST - 数据库所在的机器 domian id SID-数据的 service n
13、ameaq.connection = DriverManager.getConnection(jdbc racle:thin:HOST:1521:SID,aquser,aquesr/aq.connection.setAutoCommit(false);然后我们通过传入 AQ connection 来获取 AQ session 对象/loads the Oracle AQ driver Class.forName(oracle.AQ.AQOracleDriver ;aq.session = AQDriverManager.createAQSession(aq.connection);上述工作做好
14、后,我们可以获取我们需要的 queue 对象了,进行出列的操作。AQQueue queue = aq.session.getQueue(aqadm,MESSAGE_QUEUEAQDequeueOption dequeueOption = new AQDequeueOption();System.out.println(Waiting for message to dequeue. ;AQMessage message = (AQOracleQueue)queue).dequeue(dequeueOption,QUEUE_MESSAGE_TYPE.getFactory();把 raw paylo
15、ad 转换成我们消息类型AQObjectPayload payload = message.getObjectPayload();QUEUE_MESSAGE_TYPE messageData = (QUEUE_MESSAGE_TYPE) payload.getPayloadData();mit();System.out.println(Dequeued no: + messageData.getNo();System.out.println(Dequeued title: + messageData.getTitle);System.out.pritnln(Dequeued text: + messageData.getText();