使用节点js从Oracle AQ中提取消息

时间:2019-01-11 11:12:55

标签: node.js oracle queue

如何使用nodejs从/向Oracle Advanced Queue(OAQ)提取消息/将消息推送到其中?

1 个答案:

答案 0 :(得分:2)

更新:对AQ RAW队列的本地支持位于GitHub上的node-oracledb 4.0的开发分支中,请参见https://github.com/oracle/node-oracledb/issues/362#issuecomment-488866833


下面是一些新的文本,这些文本将在下一个node-oracledb文档的推送中出现:

Oracle Advanced Queuing允许应用程序使用 生产者-消费者消息传递。 Oracle AQ是高度可配置的。 消息可以由多个生产者排队。不同的消费者可以 为他们过滤消息。消息也可以传播到队列 在其他数据库中。 Oracle AQ具有PL / SQL,Java,C和HTTPS 接口,允许许多应用程序通过消息进行通信。 在node-oracledb中,当前通过以下方式使用PL / SQL接口 显式调用。

以下示例显示了如何使一个简单的队列入队和出队 消息。

首先,创建一个具有创建权限的新Oracle用户demoqueue 并使用队列。以SYSDBA身份连接并运行:

CREATE USER demoqueue IDENTIFIED BY welcome;
ALTER USER demoqueue DEFAULT TABLESPACE USERS QUOTA UNLIMITED ON USERS;
GRANT CONNECT, RESOURCE TO DEMOQUEUE;
GRANT AQ_ADMINISTRATOR_ROLE, AQ_USER_ROLE TO demoqueue;
GRANT EXECUTE ON DBMS_AQ TO demoqueue;
GRANT CREATE TYPE TO demoqueue;

此示例中的消息包含名称和地址。创建一个 有效负载类型,并为此有效负载启动队列,请连接 作为新的demoqueue用户并运行:

-- For the data we want to queue
CREATE OR REPLACE TYPE USER_ADDRESS_TYPE AS OBJECT (
   NAME        VARCHAR2(10),
   ADDRESS     VARCHAR2(50)
);
/

-- Create and start a queue
BEGIN
 DBMS_AQADM.CREATE_QUEUE_TABLE(
   QUEUE_TABLE        =>  'DEMOQUEUE.ADDR_QUEUE_TAB',
   QUEUE_PAYLOAD_TYPE =>  'DEMOQUEUE.USER_ADDRESS_TYPE');
END;
/

BEGIN
 DBMS_AQADM.CREATE_QUEUE(
   QUEUE_NAME         =>  'DEMOQUEUE.ADDR_QUEUE',
   QUEUE_TABLE        =>  'DEMOQUEUE.ADDR_QUEUE_TAB');
END;
/

BEGIN
 DBMS_AQADM.START_QUEUE(
   QUEUE_NAME         => 'DEMOQUEUE.ADDR_QUEUE',
   ENQUEUE            => TRUE);
END;
/

两个帮助程序使消息入队和出队的函数将使调用 排队更容易。在demoqueue用户运行时:

CREATE OR REPLACE PROCEDURE my_enq(
       user_addr_p IN user_address_type) AS
  ENQUEUE_OPTIONS    DBMS_AQ.ENQUEUE_OPTIONS_T;
  MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
  ENQ_ID             RAW(16);
BEGIN
  DBMS_AQ.ENQUEUE(QUEUE_NAME            => 'DEMOQUEUE.ADDR_QUEUE',
                  ENQUEUE_OPTIONS       => ENQUEUE_OPTIONS,
                  MESSAGE_PROPERTIES    => MESSAGE_PROPERTIES,
                  PAYLOAD               => user_addr_p,
                  MSGID                 => ENQ_ID);
  COMMIT;
END;
/
SHOW ERRORS

CREATE OR REPLACE PROCEDURE MY_DEQ(
       user_addr_p OUT USER_ADDRESS_TYPE) AS
  DEQUEUE_OPTIONS    DBMS_AQ.DEQUEUE_OPTIONS_T;
  MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
  ENQ_ID             RAW(16);
BEGIN
  DBMS_AQ.DEQUEUE(QUEUE_NAME            => 'DEMOQUEUE.ADDR_QUEUE',
                  DEQUEUE_OPTIONS       => DEQUEUE_OPTIONS,
                  MESSAGE_PROPERTIES    => MESSAGE_PROPERTIES,
                  PAYLOAD               => user_addr_p,
                  MSGID                 => ENQ_ID);
  COMMIT;
END;
/
SHOW ERRORS

使用此基本队列配置,如果调用了出队操作 如果队列中没有消息,则呼叫将阻塞 等待排队,直到队列等待时间到期。 可以配置此行为。

可以从node-oracledb以匿名方式调用帮助程序 阻止消息入队和出队:

// Enqueue a message
username = 'scott';
address  = 'The Kennel';
sql = `BEGIN
         my_enq(user_address_type(:un, :ad));
       END;`;
binds = {un: username, ad: address};
await connection.execute(sql, binds);

// Dequeue a message
sql = `DECLARE
         ua user_address_type;
       BEGIN
         my_deq(ua);
         :un := ua.name;
         :ad := ua.address;
       END;`;
binds = {un: {dir: oracledb.BIND_OUT}, ad: {dir: oracledb.BIND_OUT}};
result = await connection.execute(sql, binds);
console.log(result.outBinds);

输出为:

{ un: 'scotty', ad: 'The Kennel' }

排队是高度可配置和可扩展的,提供了一种很好的方式 分配Web应用程序的工作负载。 Oracle AQ可用于 数据库的所有版本。