Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Nicola.

Asked: September 29, 2008 - 11:07 am UTC

Last updated: September 10, 2012 - 6:15 pm UTC

Version: 9.2 to 10.2

Viewed 1000+ times

You Asked

Hello,

I need an advice about which is the best way/architecture to accomplish the following:
when user A changes a record of a particular table and commits it, user B needs to be notified of this change in some way.
We can choose later if application should automatically refresh the changed table, or if the user is simply adviced to do so.
The application can be client server or web based.

Polling the relevant tables is the first thing that comes to mind, but it seems
quite .... primitive ...
Searching this site I found several references to Oracle AQ for similar purposes.
Perhaps could this be the more appropriate approach ?
One problem that I see is
1. I know nothing about this feature (the classic: "we didn't know..." I guess)
2. we have clients with versions ranging from 9.2 to 10.2. Several have standard version. Will be AQ available on all of these ?
3. if AQ is the way to go may you recommend a link/tutorial to start with ?

If not AQ ... .what else may be more appropriate ?

Thank you very much for your time
Bye
Nicola

and Tom said...

In 10g:

http://www.oracle.com/pls/db102/search?remark=quick_search&word=notification&tab_id=&format=ranked

change notification can be used.


In 11g:

http://docs.oracle.com/cd/B28359_01/server.111/b28274/memory.htm#BGBBIACC

the client result cache would be an even easier approach - the client application would just issue the query over and over and we'd only execute the query if the results changed in the database.


In 9i, you are limited - change notification and client result cache is not available. There you would either

a) poll
b) use dbms_alert (very much like polling, you'd have to check the alert from time to time to see if you've been alerted to a change)


I don't see AQ here really - that is more of a producer/consumer thing.

Rating

  (10 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Link given above give errors when opened.

Girish Singhal, September 30, 2008 - 1:15 am UTC

Tom, the second link detailed above viz.

http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/memory.htmGBBIACC

gives errors when clicked. The errors says:



We're sorry, the page you requested was not found.

We have recorded this error (404) to help us fix the problem.
You may wish to try again using one of the tools below.

Back to Previous Page
Site Map
Product Index
To search for your page, try our Search function.

Warm Regards,

Tom Kyte
September 30, 2008 - 8:17 am UTC

http://docs.oracle.com/docs/cd/B28359_01/server.111/b28274/memory.htm

look for

7.6 Using the Client Query Result Cache

Client Query Result Cache

Sokrates, October 01, 2008 - 4:27 am UTC

that seems to me one of the most exciting features of 11g !

So you mean, in order to check for changes, we could re-query using the Client Query Result Cache and then check if
Invalidation Count in CLIENT_RESULT_CACHE_STATS$
was incremented ?
Tom Kyte
October 01, 2008 - 11:59 am UTC

you would not need to check anything - just issue the query, if the data was not modified - nothing will be done client/server wise - you'll just get back the answer your client had cached - if the data was modified - you will get the modified data transparently.



change notification between databases

Maverick, April 20, 2009 - 10:41 pm UTC

Tom, I was checking the link [10g Change notification] and it was very interesting. One question that was not clear from the docs is, Can I have my change notification sent to another database [pl/sql procedure] instead of a web-client?
[I mean database 2 will be waiting on change notification from database 1 and then as soon as it receives notification, query database 1 with required rows..]

If so, can you provide a link with example?
Thanks
Tom Kyte
April 21, 2009 - 3:03 pm UTC

I keep trying to tell you that change notification is not for replication. You are trying to replicate based on all your previous questions. This is not something to use change notification for. So, I will not continue down this path, it is the wrong approach.


http://docs.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_dcn.htm#ADFNS1014

... Database Change Notification is useful for an application that caches query result sets on mostly read-only objects in the mid-tier to avoid network round trips to the database. Such an application can create a registration on the queries it is interested in caching using the change notification service. On changes to objects referenced inside those queries, the database publishes a change notification when the underlying transaction commits. In response to the notification, the application can refresh its cache by re-executing the queries. ...

that is what change notification is for, it cannot be used to perform database replication.

change notification between databases

A reader, April 21, 2009 - 3:21 pm UTC

Tom, thanks for your response. I know you are trying to tell me about Replication on other questions but that's a different scenario for me. I am trying 2/3 things at a time and we are trying different technologies for different things. Replication [Streams] was for replicating a database. I understood that. But in this scenario we are implementing a 3rd party tool and we need to send data [like jobs/customer resumes etc..] to that instantly to get results back to users.
So, we were thinking to implement this in either .NET client application or a windows/web service. But since we get source data from 3-4 different applications , they all need to accomadate this web service.
or another apporach was to consider everything in database and send data to that tool instantly from database. What i read about change notification was talking mostly about client application and database.I was wondering if that's possible without client..Not sure if I am making any sense :-)

Thanks again,
Tom Kyte
April 21, 2009 - 3:59 pm UTC

... I
understood that. But in this scenario we are implementing a 3rd party tool and
we need to send data [like jobs/customer resumes etc..] to that instantly to
get results back to users.
...

that doesn't compute, you'll need to describe what you are trying to accomplish more clearly.

change notification between databases

A reader, April 23, 2009 - 8:32 am UTC

I think instead of explaining all the details ,If I rephrase my question, that would be better.
Is it possible to trigger an event when new rows are inserted in a database without using Triggers and Materialized views? If so, how? I was thinking Change notification is the only other way, but I might be wrong.
Thanks,
Tom Kyte
April 27, 2009 - 10:47 am UTC

I'll ignore this and ask you a question - what would happen if you were not there to be notified, would your plan still work. That is, you seem to want to do something when data changes - every time it changes. What if your process isn't running?

(forget triggers, just deny their existence)


data sharing techniques:

AQ - advanced queues, queue a message.
CDC - change data capture, be provided with views of changes
Streams - have the redo stream be mined by our software and have interesting events queued into AQ for you.
Materialized views - we track the changes and then synchronize some remote data with them
Advanced replication - for update anywhere, can be based on streams as well.



change data notification is designed for applications that want to cache data and be notified that their cache is invalid. If they are not running - they don't really care that they are not notified - I think you do care. And it is not for "between databases", it is for the database to notify a client.

A reader, September 01, 2011 - 2:50 pm UTC

Hi Tom,

Could you please someone advise whether the query change notification is supported by oracle 11g release1(11.1.0.7.0)?

SQL> declare
  2  reginfo cq_notification$_reg_info;
  3  v_cursor sys_refcursor;
  4  regid number;
  5  begin
  6  reginfo := cq_notification$_reg_info('testbks',DBMS_CQ_NOTIFICATION.QOS_QUERY,0,0,0);
  7  regid := dbms_cq_notification.new_reg_start(reginfo);
  8  open v_cursor for select name from kk where gid=2;
  9  close v_cursor;
 10  dbms_cq_notification.reg_end;
 11  end;
 12
 13  /
declare
*
ERROR at line 1:
ORA-29976: Unsupported query for registration in guaranteed mode
ORA-06512: at line 8


Oracle documentation cliams that it's supported from oracle 11g release 1 onwards.. here is the link

http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_cqnotif.htm

Please let me know if I am missing something here?

Regards,
Richard


Tom Kyte
September 01, 2011 - 3:03 pm UTC

what is kk in this context?

ops$tkyte%ORA11GR2> drop table kk;

Table dropped.

ops$tkyte%ORA11GR2> create table kk ( gid number primary key, name varchar2(20) );

Table created.

ops$tkyte%ORA11GR2> declare
  2    reginfo cq_notification$_reg_info;
  3    v_cursor sys_refcursor;
  4    regid number;
  5  begin
  6    reginfo := cq_notification$_reg_info('testbks',DBMS_CQ_NOTIFICATION.QOS_QUERY,0,0,0);
  7    regid := dbms_cq_notification.new_reg_start(reginfo);
  8    open v_cursor for select name from kk where gid=2;
  9    close v_cursor;
 10    dbms_cq_notification.reg_end;
 11  end;
 12  /

PL/SQL procedure successfully completed.


I get that in 11.1 and 11.2...

A reader, September 02, 2011 - 12:28 am UTC

Thanks Tom for your quick response. I am still getting the same error message. Here are the details. Please advise.

RCM_DB> create table kk ( gid number primary key, name varchar2(20) ) ;

Table created.

RCM_DB> declare
2 reginfo cq_notification$_reg_info;
3 v_cursor sys_refcursor;
4 regid number;
5 begin
6 reginfo := cq_notification$_reg_info('testbks',DBMS_CQ_NOTIFICATION.QOS_QUERY,0,0,0);
7 regid := dbms_cq_notification.new_reg_start(reginfo);
8 open v_cursor for select name from kk where gid=2;
9 close v_cursor;
10 dbms_cq_notification.reg_end;
11 end;
12 /
declare
*
ERROR at line 1:
ORA-29976: Unsupported query for registration in guaranteed mode
ORA-06512: at line 8


db parameters

RCM_DB> show parameter undo

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS3
_job_queue_interval integer 1
job_queue_processes integer 1000
dml_locks integer 1472


Version : Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit


Tom Kyte
September 02, 2011 - 8:33 am UTC

please utilize support - I cannot reproduce the issue.

client query result cache

vinod, August 23, 2012 - 5:37 am UTC

Hello Tom,

I am doing test of Client side result set cache on oracle 11 g rel2 ,O/S- RHEL

i am doing test as below on 2 Oracle 11g rel2 test servers on RHEL

one oracle 11g rel2 instance is used as server1,from other oracle 11g rel2 server2, i am running queries connecting to server1 through sqlplus,listener(tnsnames )

i run query few times without any client cache settings then
i have set init.ora paras for oracle 11g rel2 for client result cache,cache size/cache lag
i run the same query few times
in both the cases after each run i am noting statistics
select * from V$RESULT_CACHE_OBJECTS;
select * from V$CLIENT_RESULT_CACHE_STATS;
select * from gv$cpool_conn_info;
also autotrace,plan etc
but after using cache this views are getting poplulated ,autotrace plan shows cache is used
but i cant see any improvement in performance after using client cache like speed,reduce network trip, etc
in fact without using cache/with no hint ,query executes faster

let me know if i am missing something,i believe sqlplus internally using OCI
or i can see the benefits of this feature through some application code etc

Thanks in advance
Tom Kyte
August 29, 2012 - 11:42 am UTC

give full example, tell us how to set up your test data. show us the tkprofs that show your point.

client query result cache

vinod, August 30, 2012 - 9:11 am UTC

Hello Tom,

As asked i am giving details as below
(though physical read-i/o seems to reduced with cache
but no change in network trip or execution time as expected)

Thanks

Query
select LIERID,type
,created,WTCD ,PID,reg,OWN,ADT,IPTDT,INSDT,MDLYR,SNUMVFLG,DFLG,CATDT,RP,count(anum)
from test.test1 group by
LIERID,type
,created,WTCD ,PID,reg,OWN,ADT,IPTDT,INSDT,MDLYR,SNUMVFLG,DFLG,CATDT,RP;



with cache
select /*+ RESULT_CACHE */ LIERID,type
,created,WTCD ,PID,reg,OWN,ADT,IPTDT,INSDT,MDLYR,SNUMVFLG,DFLG,CATDT,RP,count(anum)
from test.test1 group by
LIERID,type
,created,WTCD ,PID,reg,OWN,ADT,IPTDT,INSDT,MDLYR,SNUMVFLG,DFLG,CATDT,RP;





without cache
-------------------
Elapsed: 00:00:11.42

Execution Plan
----------------------------------------------------------
Plan hash value: 2701798090

--------------------------------------------------------------------------------
------

| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time
|

--------------------------------------------------------------------------------
------

| 0 | SELECT STATEMENT | | 416K| 16M| | 12426 (2)| 00:0
2:30 |

| 1 | HASH GROUP BY | | 416K| 16M| 60M| 12426 (2)| 00:0
2:30 |

| 2 | TABLE ACCESS FULL| TEST1 | 416K| 16M| | 7917 (2)| 00:0
1:36 |

--------------------------------------------------------------------------------
------



Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
35633 consistent gets
35630 physical reads
0 redo size
246582 bytes sent via SQL*Net to client
6401 bytes received via SQL*Net from client
295 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
4407 rows processed















With Cache
=========

Multiple runs time
Elapsed: 00:00:12.21
Elapsed: 00:00:06.52
Elapsed: 00:00:08.62
Elapsed: 00:00:13.73
Elapsed: 00:00:11.97








Execution Plan
----------------------------------------------------------
Plan hash value: 2701798090

--------------------------------------------------------------------------------
--------------------------

| Id | Operation | Name | Rows | Bytes |TempSp
c| Cost (%CPU)| Time |

--------------------------------------------------------------------------------
--------------------------

| 0 | SELECT STATEMENT | | 416K| 16M|
| 12426 (2)| 00:02:30 |

| 1 | RESULT CACHE | 849a9vv2hqjky7n8ktx2u62552 | | |
| | |

| 2 | HASH GROUP BY | | 416K| 16M| 60
M| 12426 (2)| 00:02:30 |

| 3 | TABLE ACCESS FULL| TEST1 | 416K| 16M|
| 7917 (2)| 00:01:36 |

--------------------------------------------------------------------------------
--------------------------


Result Cache Information (identified by operation id):
------------------------------------------------------

1 - column-count=16; dependencies=(SIEBEL.TEST1); parameters=(nls); name="s
elect /*+ RESULT_CACHE */ LIERID,type
,created,WTCD ,PID,reg,OWN,ADT,IPTDT,INSDT,MDLYR,SNUMVFLG,DFLG,CATDT,RP"



Statistics
----------------------------------------------------------
3 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
246599 bytes sent via SQL*Net to client
6401 bytes received via SQL*Net from client
295 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
4407 rows processed





Tom Kyte
September 10, 2012 - 6:15 pm UTC

probably, you are timing the time it takes to paint your screen, you don't tell us what you are doing to actually run this.

is it traceonly - or dump data and trace?

use dbms_monitor to enable tracing and tkprof to report the time spent in the database.


anything else (all other time) is network, screen updating, etc. nothing we can do about that.

client query result cache

A reader, September 05, 2012 - 3:07 am UTC

Hello Tom,

Uploaded test/output result as above

thanks

More to Explore

DBMS_ALERT

More on PL/SQL routine DBMS_ALERT here