`
yangzb
  • 浏览: 3503382 次
  • 性别: 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

分享到:
评论

相关推荐

    oracle data change notification,支持10.2以上的Oracle版本,速度很快,效率高

    总之,Oracle Data Change Notification是一个强大的工具,能够帮助开发人员构建高性能、低延迟的应用程序,尤其是在需要实时数据同步的场景下。正确理解和运用DCN,对于提升系统效率和用户体验具有重要意义。

    Registered State Change Notification

    Registered State Change Notification

    Notification小例子

    "Notification小例子"是针对这一主题的一个示例项目,旨在帮助开发者了解并掌握如何在Android平台上创建和管理Notification。 Notification的基本结构包括以下几个部分: 1. **通知频道(Notification Channel)**...

    android Notification使用例子

    本项目是一个基于Android 2.3(Gingerbread)版本的小实例,旨在帮助开发者学习如何使用Notification API创建和管理通知。 首先,创建Notification需要使用`NotificationCompat.Builder`类,它是Android Support ...

    Notification

    在Android开发中,`Notification`是用户界面的一个关键组件,用于在状态栏向用户显示重要的信息或提醒。在"疯狂Android中有关Notification的简单例子"这个主题中,我们将深入探讨`Notification`的基本概念、创建过程...

    Android-json2notification-一个多功能方便好用的notification通知栏通知开源库

    在这个例子中,我们为Notification添加了两个动作按钮:“删除”和“取消”,每个按钮都绑定了一个特定的Intent,当用户点击时,对应的Action会被执行。 此外,`json2notification`库可能还包含了自定义扩展的功能...

    android Notification 例子

    一个Notification通常包括以下组件: 1. **通知标题(title)**:简短地概述通知的主要内容。 2. **通知内容(text)**:详细描述通知的信息。 3. **图标(icon)**:代表应用的可视标识,通常显示在状态栏和通知...

    Notification最新用法、实现Notification的通知栏常驻、Notification的big View、解决Notification点击无效

    - 另一个常见方法是使用Foreground Service,它会显示一个持续的Notification,即使应用在后台运行也不会被系统杀死。 3. **Notification的big View样式** - big View是Android引入的一种扩展通知,可以展示更多...

    android notification完全解析Demo

    本文将深入解析Android Notification的工作原理、设计模式以及如何创建一个完整的Demo。 一、Notification概述 Notification是Android系统提供的一种通知用户的应用程序事件的方式,它可以在状态栏中显示图标、文字...

    Android 在状态栏添加Notification信息图标及提示.rar

    这个例子演示Android 在状态栏添加Notification信息图标及提示,相信大家对这个功能已经不陌生了,手机中安装的APP,一般都会在后台运行,时不时会在手机顶部的状态栏中显示应用的图标,滑出状态栏会看到详细的信息...

    Notification的示例源码

    在Android开发中,`Notification`是用户界面的一个关键组件,用于在状态栏中显示消息,即使应用程序在后台运行,也能提醒用户有新的活动或事件发生。`Notification`的设计旨在提供一致且非侵入性的用户体验,使得...

    Delegate与Notification区别的一个小试验

    相对而言,通知(Notification)是广播机制,允许一个对象向系统中的任何其他对象发布消息,而无需知道接收者是谁。这种一对多的关系使得通知在需要广泛传播信息时非常有用。在实验中,可能会创建一个NSNotification...

    Notification Demo

    "Notification Demo"是一个示例项目,专门展示了如何在Android应用中实现通知功能。下面我们将深入探讨Android通知的原理、使用方法以及在`NotificationDemo`中可能包含的关键代码。 首先,通知在Android系统中由`...

    Ext JS Notification 插件

    在Ext JS中,“Notification”插件是用于显示通知消息的一个组件,它可以帮助开发者在用户界面上创建吸引人且易于理解的提示信息。本文将深入探讨Ext JS Notification插件的使用方法、功能特性以及如何集成到项目中...

    实现Notification的通知栏常驻

    本教程将深入探讨如何实现这样一个常驻通知栏的Notification。 首先,我们需要了解Notification的基本结构。一个Notification通常包括以下组件: 1. **通知标题(title)**:这是用户在通知栏看到的主要信息。 2. ...

    Notification示例

    1. **普通Notification**: 这是最基础的Notification形式,通常包含标题、内容和一个或多个操作按钮。创建普通Notification通常使用`NotificationCompat.Builder`类,通过调用`setContentTitle()`, `setContentText...

    Android notification+Service实时更新

    本项目"Android notification+Service实时更新"就是利用这些组件来构建一个功能,即在后台进行文件下载并实时更新用户通知栏的状态,当下载失败时允许用户重新尝试,下载成功后可自动安装。 首先,我们来看`...

Global site tag (gtag.js) - Google Analytics