`
yangzb
  • 浏览: 3514732 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Database Change Notification的一个例子

阅读更多

ORACLE提供的Databas Change Notification特性让我们可以通过Register的形式告诉数据库,
用户对某些表的内容改变感兴趣。最常用的地方是,在数据发生变化后,刷新Mid-Tier的数据
Cache.摘录一段文档内容
--------------------------------------------------------------------------------
Database Change Notification is a feature that enables client applications to register
queries with the database and receive notifications in response to DML or DDL
changes on the objects associated with the queries. The notifications are published by
the database when the DML or DDL transaction commits.
During registration, the application specifies a notification handler and associates a set
of interesting queries with the notification handler. A notification handler can be either
a server side PL/SQL procedure or a client side C callback. Registrations are created
on all objects referenced during the execution of the queries. The notification handler
is invoked when a transaction subsequently changes any of the registered objects and
commits.
--------------------------------------------------------------------------------

使用的对象以及关系
        sys.chnf$_desc <-- sys.chnf$_tdesc <-- sys.chnf$_rdesc

SQL> desc sys.chnf$_desc
Element          Type                  
---------------- ---------------------
REGISTRATION_ID  NUMBER               
TRANSACTION_ID   RAW(8)               
DBNAME           VARCHAR2(30)         
EVENT_TYPE       NUMBER               
NUMTABLES        NUMBER               
TABLE_DESC_ARRAY SYS.CHNF$_TDESC_ARRAY

SQL> desc sys.chnf$_tdesc
Element        Type                  
-------------- ---------------------
OPFLAGS        NUMBER               
TABLE_NAME     VARCHAR2(64)         
NUMROWS        NUMBER               
ROW_DESC_ARRAY SYS.CHNF$_RDESC_ARRAY

SQL> desc sys.chnf$_rdesc
Element Type           
------- --------------
OPFLAGS NUMBER         
ROW_ID  VARCHAR2(2000)

--------------------------------------------------------------------------------
下面提供一个简单的例子(首先满足系统权限要求)
CONNECT / AS SYSDBA;
GRANT CHANGE NOTIFICATION TO T2;
GRANT EXECUTE ON DBMS_CHANGE_NOTIFICATION TO T2;
-- 如果有必要,设置参数job_queue_processes为非零(默认就是非零)
ALTER SYSTEM SET job_queue_processes=4;

------------------------------------------------------------------------------
-- create sample data
------------------------------------------------------------------------------
create table ntfn_batch as select rb.* from rps_batch rb where rb.id = 2730006;

create table ntfn_trans as
select rt.*
  from rps_transaction rt
where rt.original_rps_batch_id = 2730006
order by rt.id;

------------------------------------------------------------------------------
-- create message table
------------------------------------------------------------------------------
drop table ntfn_msg;
create table ntfn_msg
(
  ora_trans raw(8),
  tab_name  varchar2(30),
  row_id    varchar2(2000),
  dt        date default sysdate
);

------------------------------------------------------------------------------
-- create procedure to process the callback when notification occurs
------------------------------------------------------------------------------
/*
You can create a PL/SQL stored procedure that the database server invokes in
response to a change to a registered object. The procedure that receives the notification
must have the following signature, where schema_name is the name of the database
schema and proc_name is the name of the stored procedure:

PROCEDURE schema_name.proc_name( ntfnds IN SYS.CHNF$_DESC )
经过测试,这里的参数名称都必须一致 ntfnds
*/

create or replace procedure ntfs_callback(ntfnds in sys.chnf$_desc) is
  l_event_type   number;
  l_ora_trans_id raw(8);
  l_numtables    number;
  l_op_flag      number;
  l_tab_name     varchar2(100);
  l_numrows      number;
  l_row_id       varchar2(2000);
begin
  l_event_type   := ntfnds.event_type;
  l_ora_trans_id := ntfnds.transaction_id;
  l_numtables    := ntfnds.numtables;

  -- only concern table change
  if l_event_type = dbms_change_notification.EVENT_OBJCHANGE then
    -- loop each table
    for i in 1 .. l_numtables loop
      --------------------------------------------------
      -- usually we call UTL_HTTP to send a notification
      -- to WEB Server, and here we only use some tables
      --------------------------------------------------
      l_op_flag  := ntfnds.table_desc_array(i).opflags;
      l_tab_name := ntfnds.table_desc_array(i).table_name;
      -- get table name without schema name
      l_tab_name := substr(l_tab_name, instr(l_tab_name, '.') + 1);
   
      if bitand(l_op_flag, dbms_change_notification.ALL_ROWS) = 1 then
        -- no certain rowid
        insert into ntfn_msg
          (ora_trans, tab_name)
        values
          (l_ora_trans_id, l_tab_name);
      else
        -- loop each row in this table
        l_numrows := ntfnds.table_desc_array(i).numrows;
        for j in 1 .. l_numrows loop
          l_row_id := ntfnds.table_desc_array(i).row_desc_array(j).row_id;
          insert into ntfn_msg
            (ora_trans, tab_name, row_id)
          values
            (l_ora_trans_id, l_tab_name, l_row_id);
        end loop; -- end loop row
      end if;
    end loop; -- end loop table
  end if;

  commit;
end;
/

------------------------------------------------------------------------------
-- procession for registration and deregister
------------------------------------------------------------------------------
-- registration
declare
  l_reg_info sys.chnf$_reg_info;
  l_reg_id number;
  l_qosflags number;
  l_temp number;
begin
  l_qosflags := dbms_change_notification.QOS_ROWIDS;
  l_reg_info := sys.chnf$_reg_info('ntfs_callback',l_qosflags,0,0,0);
  l_reg_id := dbms_change_notification.NEW_REG_START(l_reg_info);
  -- register tables
  select count(1) into l_temp from ntfn_batch b, ntfn_trans t where b.id = t.original_rps_batch_id;  
  dbms_change_notification.REG_END;
end;
/

-- check register result
select r.regid,r.table_name from user_change_notification_regs r;

-- deregister
declare
  l_reg_id number := 23;
begin
  dbms_change_notification.DEREGISTER(l_reg_id);
end;
/  


------------------------------------------------------------------------------
-- do some change and check result after commit
------------------------------------------------------------------------------
update ntfn_batch b set b.rps_application_id=b.rps_application_id where rownum = 1;
commit;
update ntfn_batch b set b.rps_application_id=b.rps_application_id;
commit;
update ntfn_trans t set t.t2_identifier = t.t2_identifier;
commit;

select to_char(m.dt, 'yyyy-mm-dd hh24:mi:ss') dt,
       m.ora_trans,
       m.tab_name,
       m.row_id
  from ntfn_msg m
order by 1, 3, 4;

SQL>
SQL> select to_char(m.dt, 'yyyy-mm-dd hh24:mi:ss') dt,
  2         m.ora_trans,
  3         m.tab_name,
  4         m.row_id
  5    from ntfn_msg m
  6   order by 1, 3, 4;

DT                  ORA_TRANS        TAB_NAME                       ROW_ID
------------------- ---------------- ------------------------------ --------------------------------------------------------------------------------
2007-10-26 17:23:16 08004100D20D0100 NTFN_BATCH                     AAFCIbAAHAAAM5AAAA
2007-10-26 17:23:46 0A0061003ED50000 NTFN_BATCH                     AAFCIbAAHAAAM5AAAA
2007-10-26 17:24:26 0400200065D30000 NTFN_TRANS                     AAFCIcAAHAAAM8IAAA
2007-10-26 17:24:26 0400200065D30000 NTFN_TRANS                     AAFCIcAAHAAAM8IAAB
2007-10-26 17:24:26 0400200065D30000 NTFN_TRANS                     AAFCIcAAHAAAM8IAAC
2007-10-26 17:24:26 0400200065D30000 NTFN_TRANS                     AAFCIcAAHAAAM8IAAD
2007-10-26 17:24:26 0400200065D30000 NTFN_TRANS                     AAFCIcAAHAAAM8IAAE
2007-10-26 17:24:26 0400200065D30000 NTFN_TRANS                     AAFCIcAAHAAAM8IAAF

8 rows selected

从这个结果可以分析出
        执行了3个事务(简称1,2,3)
        事务1,2更改了NTFN_BATCH,事务3更改了NTFN_TRANS

分享到:
评论

相关推荐

    java实现监听数据库源码

    Java 6引入了一个新的特性——Java Database Change Notification,允许应用程序订阅数据库的改变。当数据库中的指定表发生变化时,JDBC驱动会通知订阅者。这是一个相对低级别的API,需要对数据库驱动有深入理解...

    DeepSeek入门宝典:赋能开发者实战的高性能AI解决方案

    内容概要:本文档详细介绍了 DeepSeek 这一高效、经济的人工智能解决方案,旨在为企业端、产品端以及开发者提供深度技术支持。对于企业而言,DeepSeek 带来了显著的成本效益和生产效率提升;而对于具体的产品和服务,它增强了用户体验的质量。特别是针对开发者,文档深入浅出地讲解了如何利用 DeepSeek 实现自动化代码生成、改写等辅助开发功能,并且提供了具体的步骤指导以满足不同环境下的部署需求,包括直接通过官方API接入、本地私有化部署或借助云平台进行托管的方式。 适合人群:希望降低开发门槛,提高工作效率的软件工程师和技术团队。 使用场景及目标:开发者可以根据自身条件选择最适合自己的部署方案来整合 DeepSeek 技术,进而达到优化编码过程、减少人为错误的目的。 其他说明:文中还包括了许多实际操作的例子,如通过代码改写的实例来展示如何改进现有程序段落,还有详细的API使用指南帮助初学者快速上手DeepSeek。此外,还提供了大量外部参考资料链接以便进一步扩展知识和技能范围。

    lusted_3cd_01_0318.pdf

    lusted_3cd_01_0318

    开源AI工具下载——Cherry-Studio-1.0.1-MACOS arm64版

    Cherry Studio是一款支持多模型服务的 Windows/macOS GPT 客户端。通过与Ollama搭配,搭建个人本地AI大模型

    chromedriver-win64-136.0.7058.0.zip

    chromedriver-win64-136.0.7058.0.zip

    matlab程序代码项目案例:使用 Simulink 进行自适应 MPC 设计

    matlab程序代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    mellitz_3cd_01_1116.pdf

    mellitz_3cd_01_1116

    基于MATLAB的牛顿迭代法实现

    基于MATLAB的牛顿迭代法实现

    steenman_01_0908.pdf

    steenman_01_0908

    [AB PLC例程源码][MMS_047737]System Time 64Bit Interpreted AOI.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    stone_3ck_01a_0518.pdf

    stone_3ck_01a_0518

    [AB PLC例程源码][MMS_041473]Input Time Stamping.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    lusted_3cd_01_1117.pdf

    lusted_3cd_01_1117

    2010-2023年 上市公司-管理层情感语调数据.zip

    管理层情感语调,或称为管理层语调,是一个在财务与会计领域中常用的概念,特别是在分析上市公司信息披露质量时。它主要指的是管理层在上市公司文字信息披露过程中,用词所体现出的情感倾向和可理解性。 本数据复刻了《财经研究》《中南财经政法大学学报》等顶级期刊的核心解释变量的做法。情感语调对企业未来盈余和未来绩效具有较强解释力、降低会计信息误定价、为分析师预测提供增量信息,而投资者也会对管理层情感语调做出积极反应。 情感语调1=(正面词汇数量-负面词汇数量)/词汇总量;数值越大,情感倾向越偏向正面积极。 情感语调2=(正面词汇数量-负面词汇数量)/(正面词汇数量+负面词汇数量);数值越大,情感倾向越偏向正面积极。 指标 证券代码、企业代码、年份、证券简称、行业代码、行业名称、正面词汇数量、负面词汇数量、词汇总量、句子数量、文字数量、情感语调1、情感语调2。

    mellitz_3cd_02_0318.pdf

    mellitz_3cd_02_0318

    moore_01_0909.pdf

    moore_01_0909

    lusted_3ck_02a_0119.pdf

    lusted_3ck_02a_0119

    pimpinella_3cd_01_0916.pdf

    pimpinella_3cd_01_0916

    [AB PLC例程源码][MMS_041392]Mill feed and Auxilary Control.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    li_3ck_03_0919.pdf

    li_3ck_03_0919

Global site tag (gtag.js) - Google Analytics