Oracle AQ 测试与实践记录:一个被忽视的强大功能

本文基于一份十年前的测试笔记整理,完整展示了 Oracle Advanced Queuing(AQ)的配置与使用流程,旨在推广这个强大却常被忽视的 Oracle 功能模块。

一、什么是 Oracle AQ?

Oracle AQ(Advanced Queuing,高级队列)是 Oracle 数据库内置的消息队列机制,支持异步通信、可靠传输、事务一致性、跨数据库传播等特性。

它可以广泛应用于:

  • 系统间消息解耦

  • 异步任务处理

  • 审计日志收集

  • 与 JMS 接轨等场景

 

二、测试环境概述

  • 源库(LCODUAT): Oracle 10.2.0.4,SID = ora10204

  • 目标库(LPHSUAT2): Oracle 10.2.0.4,SID = orcl

  • 测试用户: temp_admin,授予 DBA 权限

  • 通信方式: 数据库链接(DBLINK)

 

三、基本对象定义与队列配置 

-- 创建测试类型
CREATE OR REPLACE TYPE temp_admin.TEST_SAF_STDIN_TYP AS OBJECT (
  fun VARCHAR2(1000),
  silly NUMBER(8)
);

 创建队列表和队列

BEGIN
  DBMS_AQADM.CREATE_QUEUE_TABLE(
    queue_table        => 'TEST_SAF_STDN_TAB',
    queue_payload_type => 'SYS.ANYDATA',
    multiple_consumers => TRUE
  );

  DBMS_AQADM.CREATE_QUEUE(
    queue_name  => 'TEST_SAF_STDN_Q',
    queue_table => 'TEST_SAF_STDN_TAB'
  );

  DBMS_AQADM.START_QUEUE(queue_name => 'TEST_SAF_STDN_Q');
END;

 添加订阅者

DECLARE
  sub SYS.AQ$_AGENT;
BEGIN
  sub := SYS.AQ$_AGENT('sub1', NULL, NULL);
  DBMS_AQADM.ADD_SUBSCRIBER(
    queue_name    => 'TEST_SAF_STDN_Q',
    subscriber    => sub,
    delivery_mode => DBMS_AQADM.PERSISTENT
  );
END;

四、消息发送与接收

Enqueue 示例(入队) 

DECLARE
  e_opt DBMS_AQ.ENQUEUE_OPTIONS_T;
  m_prop DBMS_AQ.MESSAGE_PROPERTIES_T;
  m_handle RAW(16);
  message ANYDATA;
BEGIN
  message := ANYDATA.CONVERTOBJECT(TEST_SAF_STDIN_TYP('testtesttest', 172));

  DBMS_AQ.ENQUEUE(
    queue_name         => 'TEST_SAF_STDN_Q',
    enqueue_options    => e_opt,
    message_properties => m_prop,
    payload            => message,
    msgid              => m_handle
  );

  COMMIT;
END;

Dequeue 示例(出队) 

DECLARE
  d_opt DBMS_AQ.DEQUEUE_OPTIONS_T;
  m_prop DBMS_AQ.MESSAGE_PROPERTIES_T;
  m_handle RAW(16);
  message ANYDATA;
  obj TEST_SAF_STDIN_TYP;
  ret PLS_INTEGER;
BEGIN
  d_opt.navigation := DBMS_AQ.FIRST_MESSAGE;
  d_opt.consumer_name := 'sub1';
  d_opt.wait := DBMS_AQ.NO_WAIT;

  DBMS_AQ.DEQUEUE(
    queue_name         => 'TEST_SAF_STDN_Q',
    dequeue_options    => d_opt,
    message_properties => m_prop,
    payload            => message,
    msgid              => m_handle
  );

  ret := message.GETOBJECT(obj => obj);
  DBMS_OUTPUT.PUT_LINE('Stuff: ' || obj.fun || ' and ' || obj.silly);
  COMMIT;
END;

 

五、跨库传播测试(Queue Propagation)

我们通过 DBLINK 实现两个库之间的异步消息传播:

-- 源库创建 DBLINK
CREATE DATABASE LINK LPHSUAT2 
CONNECT TO temp_admin IDENTIFIED BY temp_admin 
USING 'ORCL';

-- 目标库也需要反向 DBLINK
CREATE DATABASE LINK LCODUAT 
CONNECT TO temp_admin IDENTIFIED BY temp_admin 
USING 'ORA10204';

 启用传播计划

BEGIN
  DBMS_AQADM.SCHEDULE_PROPAGATION(
    queue_name   => 'TEST_SAF_STDN_Q',
    destination  => 'LPHSUAT2'
  );
END;

 可选:启用/禁用/修改传播计划

-- 停用
BEGIN
  DBMS_AQADM.DISABLE_PROPAGATION_SCHEDULE(
    queue_name  => 'TEST_SAF_STDN_Q',
    destination => 'LPHSUAT2'
  );
END;

-- 修改调度策略
BEGIN
  DBMS_AQADM.ALTER_PROPAGATION_SCHEDULE(
    queue_name  => 'TEST_SAF_STDN_Q',
    destination => 'LPHSUAT2',
    duration    => '1',
    next_time   => 'SYSDATE + 1/1440',
    latency     => '32'
  );
END;

-- 启用
BEGIN
  DBMS_AQADM.ENABLE_PROPAGATION_SCHEDULE(
    queue_name  => 'TEST_SAF_STDN_Q',
    destination => 'LPHSUAT2'
  );
END;

六、调试与故障处理

常见问题:

  • ORA-12514: 目标库未启动或监听未识别服务名

  • J000 进程未工作: 可手动 kill 后由 PMON 重启

  • DBLINK 超时: 检查防火墙/TNS 配置/监听状态

观察视图: 

-- 队列状态
SELECT * FROM dba_queues WHERE owner = 'TEMP_ADMIN';

-- 传播计划状态
SELECT * FROM dba_queue_schedules 
WHERE schema = 'TEMP_ADMIN' AND qname = 'TEST_SAF_STDN_Q';

-- 消息队列内容
SELECT * FROM AQ$TEST_SAF_STDN_TAB;

 

七、总结与推荐

Oracle AQ 虽然已有多年历史,但在实际项目中却常被忽视。相比外部消息中间件,它具备以下优势:

  • 集成度高: 无需外部组件,即可事务一致

  • 可控性强: 支持复杂订阅者模型、调度机制

  • 跨库通信: 原生 DBLINK 支持异步传播

  • 易于管理: 系统视图和调度机制完善

适合场景:

  • 核心系统间的可靠消息传递

  • 异步任务的简易实现

  • 审计/日志/业务事件通知等

如果你在项目中需要轻量级的消息中间件,Oracle AQ 可能就是你最不该忽略的答案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值