Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Winston.

Asked: March 30, 2003 - 5:33 pm UTC

Last updated: May 10, 2006 - 9:05 am UTC

Version: 9iR2

Viewed 1000+ times

You Asked

Hi Tom,

I am rereading your 1st book page 114 about locking and cocurrency. I wonder if we can still use the "select XIDUSN, XIDSLOT,XIDSQN from v$transaction' to uniquely identify a transaction with the introducton of automatic undo management mode in Oracle9i. And if we could still user the following query to get (rbs, slot, seq) and compare it with the result (xidusn, xidslot, xidsqn) from v$transaction.
select username, v$lock.sid,
trunc(id1/power(2,16)) rbs,
bitand(id1,to_number('ffff','xxxx'))+0 slot,
id2 seq, lmode, request, block
from v$lock, v$session
where v$lock.type='TX'
and v$lock.sid=v$session.sid
and v$session.username=USER

Thank you in advance,
Winston


and Tom said...

To to show that you learn new things every day -- between the time I wrote the book and now -- I've found an easier way:

ops$tkyte@ORA920> select dbms_transaction.local_transaction_id from dual;

LOCAL_TRANSACTION_ID
-----------------------
13.36.60919

ops$tkyte@ORA920> select XIDUSN, XIDSLOT,XIDSQN from v$transaction;

XIDUSN XIDSLOT XIDSQN
---------- ---------- ----------
13 36 60919


but yes, it would work with UNDO tablespaces since they are just rollback segments in disguise.

Rating

  (8 ratings)

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

Comments

Does ORACLE recycle transaction ID?

Jusung Yang, March 31, 2003 - 3:05 am UTC

Hi Tom,

There was a thread at comp.databases.oracle.server about the uniqueness of transaction ID. Used to be that transaction ID can run out and the associated rollback segment needs to be dropped and recreated. I wonder how the the ORACLE 9i auto
undo management handles this. Will ORACLE recycle transaction IDs? If not, what happens when the transaction IDs run out?

Tom Kyte
March 31, 2003 - 8:29 am UTC

the rbs's in the undo tablespace are created, dropped, resized all of the time. It is interesting to monitor your alert log -- ramp up concurrent users and watch the database automatically create and online new rbs to handle the load -- and if you are patient enough, watch it offline and drop them later when they are not needed anymore.

dbms_transaction.local_transaction_id

vc, August 28, 2003 - 5:41 pm UTC

Dear Tom,

Please consider this:

SQL*Plus: Release 9.2.0.3.0 - Production on Thu Aug 28 17:35:07 2003

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production


Case 1:
=======
SQL> SET TRANSACTION READ ONLY;

Transaction set.

SQL> select select XIDUSN, XIDSLOT,XIDSQN from v$transaction;

SQL> select XIDUSN, XIDSLOT,XIDSQN from v$transaction;

no rows selected

SQL> commit;

Commit complete.

SQL> select XIDUSN, XIDSLOT,XIDSQN from v$transaction;

no rows selected


Case 2:
=======
SQL> SET TRANSACTION READ ONLY;

Transaction set.

SQL> select XIDUSN, XIDSLOT,XIDSQN from v$transaction;

no rows selected

SQL> SELECT dbms_transaction.local_transaction_id FROM dual;

LOCAL_TRANSACTION_ID
------------------------------------------------------------------------------

7.19.23877

SQL> select XIDUSN, XIDSLOT,XIDSQN from v$transaction;

    XIDUSN    XIDSLOT     XIDSQN
---------- ---------- ----------
         7         19      23877

SQL>

=================

Is it a bug in dbms_transaction.local_transaction_id or expected behaviour and,  if the latter,  why in Case 1 there is no transaction record in v$transaction ?

Thank you.
 

Tom Kyte
August 29, 2003 - 9:01 am UTC

it would be a bug if you were able to actually update something.


ops$tkyte@ORA920> SELECT dbms_transaction.local_transaction_id FROM dual;
 
LOCAL_TRANSACTION_ID
-----------------------------------------------------------------------------------------------------------------------------------
4.9.19278
 
ops$tkyte@ORA920> update emp set empno = empno;
update emp set empno = empno
       *
ERROR at line 1:
ORA-01456: may not perform insert/delete/update operation inside a READ ONLY transaction


but you cannot. so, no bug... you are "read only"


In case #1, why would you "expect" a record in v$transaction?  you don't really "need" one 

dbms_transaction.local_transaction_id

vc, August 29, 2003 - 9:19 am UTC

OK, probably I was not clear enough.

You said:
"In case #1, why would you "expect" a record in v$transaction? you don't really "need" one "

I never expected any record in v$transaction in Case 1. Thank you for confirming that.

Now as to Case 2, the real question is:

Why does running 'SELECT dbms_transaction.local_transaction_id FROM dual;' creates an entry in v$transaction ? That's what my Case 2 demonstrates. Clearly there is no update/delete/insert.

dbms_transaction.local_transaction_id creating this entry is quite misleading. What's the point of having a transaction id for the read-only transaction (isolation level read-only) ?

Thank you.



Tom Kyte
August 29, 2003 - 10:39 am UTC

well -- you sort of asked for one didn't you?

the act of asking -- makes one appear. why is it misleading -- you are *in* a transaction. we didn't need to identify that transaction -- well, not until you said "please -- identify this transaction for me" any way...

using the set transaction "created a transaction" -- you were in one explicity! when you asked for the identifier -- it became "exposed".

vc, August 29, 2003 - 11:06 am UTC

OK.

The transaction information appearing as the result of calling the function is misleading for several reasons:

1. You said 'why would you "expect" a record in vtransaction? you don't really "need" one'. That's a fair statement for the read-only transaction -- after all it (the transaction) does not generate undo and, therefore, the transaction id (XIDUSN, XIDSLOT, XIDSQN) does not have any meaning in the context of the read-only transaction.

2. Taking the above into account, what's the real meaning of the transaction id created as a result of dbms_transaction.local_transaction_id execution ? Just a number without any meanining ? If so, what's the use of such a number ?

3. Does Oracle create a 'real' transaction entry in v$transaction where XIDUSN, XIDSLOT, XIDSQN have the usual semantics just in order to return a transaction id ? If so, it's quite counter-intuitive for someone accustomed to seeing entries in v$transaction only for update/insert/deletes.

Thanks.


Tom Kyte
August 29, 2003 - 12:17 pm UTC

sorry -- sometimes the answer is just "it is the way it is"

i fail to see why this particular behaviour is confusing, or bothersome, or having any effect at all really on you.

you started a transaction
you asked for the transaction id
we gave it to you

i don't know exactly why it isn't visible in the v$ tables until you ask for it but -- so?


#2 -- you can use it to uniquely identify your transaction for whatever purpose you see fit.

#3 -- there are other times you'll see it in there. touch a dblink for example and see what happens. lock a table. there are other times.


one would be wondering (i sure am)

"if you don't know what to do with this value,
and it bothers you that when you ask for the value something else happens
and yet you have no purpose for this value,
why are you asking for the value,
thus causing the undesired side effect???"






More inconsistency with dbms_transaction.local_transaction_id

vc, August 29, 2003 - 11:40 am UTC

You said 'the act of asking -- makes one appear.  why is it misleading -- you are *in* a transaction.'

Consider this:

SQL>  alter session set isolation_level=serializable;

Session altered.

SQL> select * from t;

         X
----------
         1

SQL> SELECT dbms_transaction.local_transaction_id FROM dual;

LOCAL_TRANSACTION_ID
--------------------------------------------------------------------------------
16.81.7410

/* So far so good -- I am in the transaction */
SQL> commit;

Commit complete.

SQL> alter session set isolation_level=read committed;

Session altered.

SQL> select * from t;

         X
----------
         1

SQL> SELECT dbms_transaction.local_transaction_id FROM dual;

LOCAL_TRANSACTION_ID
--------------------------------------------------------------------------------

/* How come ? I am not in a transaction ? Or a transaction running in the READ COMMITTED mode is not quite a transaction */

SQL> commit;

Commit complete.

SQL>


Wouldn't you agree that the behaviour is quite inconsistent ?  Under the SERIALIZABLE/READ-ONLY level I can get a transaction id plus an entry in v$transaction as a bonus whilst in READ COMMITTED I get nothing ? As an aside,  I do understand how read consistency is achieved in both mode and one can probably rationalize why dbms_transaction.local_transaction_id behaves differently but it would not make the behaviour consistent surely.

Thanks. 

Tom Kyte
August 29, 2003 - 12:26 pm UTC



guess if you think this is something that is broken and needs to be fixed, you'll need to goto support and file a tar to get a bug going.


but -- if you think about the very definition of serializable -- maybe you'll figure it out....

serializable means "i'm ALWAYS in a transaction -- ALWAYS. Transactions begin with the FIRST STATEMENT regardless of type..."

read committed -- well -- it doesn't mean that.

Reader

A reader, November 05, 2003 - 12:18 am UTC

"
the rbs's in the undo tablespace are created, dropped, resized all of the time.
It is interesting to monitor your alert log -- ramp up concurrent users and
watch the database automatically create and online new rbs to handle the load --
and if you are patient enough, watch it offline and drop them later when they
are not needed anymore.
"

1. Is there a view to monitor rbs dropped and rbs added
2. Leaving aside "flashback queries" what is the best way
to monitor and resize undo tablespace, to optimal size

Tom Kyte
November 05, 2003 - 8:28 am UTC

1) dba_rollback_segs show you what is there, the history is only in the alert

2) determine how long you anticipate having your longest running query run for. set the undo_retention to some period of time larger then that. I like to let the undo tablespace autoextend naturally to be large enough by itself rather then size it manually -- but you can use v$undostat (OEM gives you a nice graphic) to right size it based on your observed workload (eg: you have to actually be running at load in order to accurately determine "how much undo space would I need to have 5 hours of retained undo")

hi

bashar, February 19, 2006 - 8:42 am UTC

how can i put icon on button in oracale 9i and how can i save on client?

dbms_transaction.local_transaction_id in triggers?

shailesh saraff, May 10, 2006 - 6:35 am UTC

Hello Tom,

I have one requirement, in one single transaction I have to do some processing only once. To address this requirement I am planning to use dbms_transaction.local_transaction_id.

Means on update <BaseTable> trigger executes and does insertion in some other tables, but in some transaction if I update same table multiple times (irrelevant of old/new values) NO insertion should happen in other tables.

Could you please elaborate on this as it is not clear to me how to reset package variable at the end of the transaction.

Please help, i would appreciate if you provide an example.

Thanks & Regards,

Shailesh




Tom Kyte
May 10, 2006 - 9:05 am UTC

using the local transaction id you would not reset a package variable at the end, you would compare the first time around


in trigger


...
if local-transaction-id <> your_packge.last_trans_id
then
do whatever
your_package.last_trans_id := local-transaction-id
end if



More to Explore

DBMS_TRANSACTION

More on PL/SQL routine DBMS_TRANSACTION here