thanks, and a related question on tx starting
Alberto Dell'Era, July 31, 2004 - 6:41 pm UTC
Thanks for the interesting insights - i didn't think about the multi-statement tx; yes, that's for sure a strong reason to keep the tm lock.
About the tx start, i take this as "started logically", since physically it seems that it doesn't start:
TX_A>create table t (x int);
Table created.
TX_B>delete from t;
0 rows deleted.
TX_A>select XIDUSN from v$transaction;
no rows selected
TX_B>insert into t(x) values (1);
1 row created.
TX_A>select XIDUSN from v$transaction;
XIDUSN
----------
1
So: is it correct that the transaction didn't start physically, or it's the other way around: the tx started and got recorded in the kernel, and it is just a quirk of v$transaction that doesn't "see" the started tx ?
[I know that v$transaction is mostly a view on the rbs headers, and since the nothing-deleting delete doesn't create undo, perhaps v$transaction is blind here].
Thanks
Alberto
July 31, 2004 - 7:01 pm UTC
the transaction has for all intents and purposes begun with the delete statement. That there wasn't a physical transaction id assigned is an optimization (just like issuing a commit when nothing need be done is optimized away as a "no-op")
ok, thanks
Alberto Dell'Era, July 31, 2004 - 7:07 pm UTC
about tx lock
gaoyf, September 26, 2005 - 5:12 am UTC
hello,Tom
I have two session.
session 1:delete from t where ...
session 2:
LOOP
BEGIN
select ... from t for update nowait
EXIT;
EXCEPTION
WHEN busy THEN
NULL;
dbms_lock.sleep(5);
END;
END LOOP;
when session 1 and 2 run at the sames time,session 1 is blocked and never unlocked because of TX lock hold by session 2;session 2 is running never end because of TX lock hold by session 1.
The oracle database unlock a TX lock only when the blocker tracsaction end ?
In the sample,session 2 get resurce busy and relases the TM lock in table t ,but session 1 always blocked by session2,because the transcation of session 2 is not end.
Why oracle not detect a TM relase for locked object of blocker process to unlock the blocked process ?
This may improve concurrent performance?
Thanks a bunch!
This is a useful site in the world!
September 26, 2005 - 9:18 am UTC
Oracle blocks at the transaction level, when the delete gets blocked, it gets blocked on the TX of session 2, until session 2 commits or rolls back - it will be blocked.
This is the way it works.
TX lock
A reader, September 26, 2005 - 11:08 pm UTC
oracle unlock a session at transaction level,not at locked objects level?Can you tell me why ?
oracle do it this way,just 'like it' or some technical reason or need to promote ?
In the above sample,session 2 release TM lock on table t because of resource busy,the table t only locked by session 1,but it blocked too.This is not a deadlock in oracle,but a deadlock in deed.
In session2 ,it locks manay many rows in many tables to process,Now I must lock one by one by 'select ... from ... for update nowait' ,if any busy,must rollback and lock again from beginning.Can you give me a better method?
Thanks!
September 27, 2005 - 10:43 am UTC
because we do not have a list of row locks anywhere, that would not be a very scalable solution - the row locks are attributes of the data. When you commit, we do not revisit every single row you updated to "unlock it", we rather remove the transaction entry.
Hence, when you get blocked - you get blocked on a transaction (not a session, not a row - a transaction). when that transaction is finished, you become unblocked. If you just hung out and waited for the status on the row to change, you might wait for a long long long time...
It is not a deadlock indeed, if it were, you would get an ora-60. One of your sessions is alive, well, and processing.
Seems your session trying to lock many many rows in many many tables needs to either
a) lock the tables - rolling back if it cannot
b) try to lock many many many rows in many many tables - rolling back if it cannot.
about TX lock
gaoyf, September 27, 2005 - 9:47 pm UTC
I do not say row locks,but say:can oracle detect TM lock releasing of blocker session to unlock blocked session ?
In sample,session 2 release all row locks and TM lock on table t because of resource busy(you lost TM locks on table,you lost all row locks on table,oracle can detect TM lock releasing ,ok?),session 1 can run because of no blocked resource in deed ?
oracle use only TX lock releasing to unlock blocked session,i think thier must be some technical reason,or why not use TM lock releasing on critical table of blocker session?
In my sample,session 1 is blocked forever,session 2 is run run run and never end forever,this is just not a deadlock and ora-60 in oracle.deadlock or deadloop or dead????, a symbol ? I have not a right word to describe it,maybe deadlockloop ? Just for fun.
Thanks very much.
September 28, 2005 - 9:17 am UTC
Looking at your application design, this is something such that the odds of the select for update ever succeeding would be near zero - very near zero - over time.
We block on the transaction - not on the block, row, segment - but the transaction.
If you used "wait", you would have a real deadlock, but because you use nowait intentionally, you don't have a true deadlock, you have an application issue, but not a deadlock in this case.
Don't know what else to tell you other than "that application logic needs to be looked at"
Why do you need the select for updates in this case? What is the real logic behind the logic - the "goal"
To know the time when a table was created or modified
A reader, January 08, 2006 - 10:38 pm UTC
Hi Tom,
How to know the time when a table was created or modified in Oracle ? By modified I mean the time when an additional column was added to the table.
January 09, 2006 - 7:58 am UTC
there is a created and last_ddl_time in the dictionary.
ops$tkyte@ORA10GR2> create table t ( x int );
Table created.
ops$tkyte@ORA10GR2> exec dbms_lock.sleep(5)
PL/SQL procedure successfully completed.
ops$tkyte@ORA10GR2> alter table t add y int;
Table altered.
ops$tkyte@ORA10GR2> select created, last_ddl_time from user_objects where object_name = 'T';
CREATED LAST_DDL_TIME
-------------------- --------------------
09-jan-2006 07:52:10 09-jan-2006 07:52:15
Avoiding TM lock
Zilvinas, May 08, 2025 - 7:30 am UTC
People do things like this to avoid TM lock
select count(1) into c from my_table where ...
if c>0 then
update my_table where ...
end if;
Does that make any sence???
How often DDLs are done in production environment ???
Is that TM lock so costly? It is only for DDL so no blcoking happens for DML.
Also this way you have two statements instead of one what is slower.
Besides there is possibility that the table is updated by another transaction between select and update statements.
Correct way would be to put "for update" in select statement, but then TM lock is aquired.
I think it is bad practice. Am I right?
May 08, 2025 - 12:24 pm UTC
You're right - counting the rows before doing update/delete is a bad idea for the reasons you've stated.
Using select for update to lock the rows first has a couple other advantages:
- You can use the (no)wait clause to time out if you can't get the lock
- It may be useful/necessary to avoid deadlock in transactions with many update/deletes to ensure rows and tables are locked in a specified order