tx tm oracle,TM / TX Locks ( Tom Kyte and Oracle Docu)

the TX lock represents "your transaction", it is "you"

the TM lock is a lock on the table itself.

when another transaction enqueues on you, it'll enqueue on your TX lock, the but fact that you have rows locked in table T is indicated by the TM lock.

I guess it is a matter of perspective/semantics. There is but one TX lock for "you", there will be a TM lock held by you on tables you've modified - and that table lock will generally be of the Row Exclusive Table Lock (RX) type - which indicates you've actually made updates to rows in table (whereas the row share - RS - lock indicates you've reserved rows for update via the select for update)

You cannot actually in truth see ANY ROW LOCKS in Oracle - they are not manifested in a memory structure to be queried up.

All you can do is look for TM locks held RS or RX and then make the claim "that transaction has some rows locked in that table"

So, the TX lock - you had one (in the above example) without touching a row in any table. When you do touch a row in a table, you get a TM lock on that table - that indicates you have row locks in there.

It is true (and probably why they wrote it the way they did in the concepts) that the TX lock is what other sessions will enqueue on (wait on). That single TX lock is what everyone else will wait one regardless of which row(s) they are trying to gain access to if you are blocking them.

That is why, by the way, a rollback to savepoint - which releases the locks gathered since the savepoint - does NOT release transactions waiting on those locks. Try this script to see what I mean by that...

change ops$tkyte to your test schema of course...

connect /

set linesize 1000

column nm format a10

drop table t;

drop user a cascade;

drop user b cascade;

drop user c cascade;

grant create session to a identified by a;

grant create session to b identified by b;

grant create session to c identified by c;

create table t ( x int );

insert into t values ( 1 );

commit;

grant all on t to public;

prompt in another session, connect as A and:

prompt savepoint foo;;

prompt update ops$tkyte.t set x = x+1;;

prompt then in another session, connect as B and:

prompt update ops$tkyte.t set x = x+1;;

prompt then come back here and hit enter....

pause

select

(select username from v$session where sid=a.sid) blocker,

a.sid,

' is blocking ',

(select username from v$session where sid=b.sid) blockee,

b.sid

from v$lock a, v$lock b

where a.block = 1

and b.request > 0

and a.id1 = b.id1

and a.id2 = b.id2

/

select sid,

(select username from v$session s where s.sid = v$lock.sid) uname,

type, id1, id2,

(select object_name from user_objects where object_id = v$lock.id1) nm

from v$lock

where sid in (select sid from v$session where username in ('A','B','C',user) )

/

prompt in session A issue:

prompt rollback to foo;;

prompt note that B is blocked, then come back here and hit enter:

pause

select

(select username from v$session where sid=a.sid) blocker,

a.sid,

' is blocking ',

(select username from v$session where sid=b.sid) blockee,

b.sid

from v$lock a, v$lock b

where a.block = 1

and b.request > 0

and a.id1 = b.id1

and a.id2 = b.id2

/

select sid,

(select username from v$session s where s.sid = v$lock.sid) uname,

type, id1, id2,

(select object_name from user_objects where object_id = v$lock.id1) nm

from v$lock

where sid in (select sid from v$session where username in ('A','B','C',user) )

/

prompt Now in another session log in as C and:

prompt update ops$tkyte.t set x = x+1;;

prompt note: it does not block - b is still blocked.

prompt then in session A issue:

prompt commit;;

prompt and come back here an hit enter

pause

select

(select username from v$session where sid=a.sid) blocker,

a.sid,

' is blocking ',

(select username from v$session where sid=b.sid) blockee,

b.sid

from v$lock a, v$lock b

where a.block = 1

and b.request > 0

and a.id1 = b.id1

and a.id2 = b.id2

/

select sid,

(select username from v$session s where s.sid = v$lock.sid) uname,

type, id1, id2,

(select object_name from user_objects where object_id = v$lock.id1) nm

from v$lock

where sid in (select sid from v$session where username in ('A','B','C',user) )

/

prompt When A committed, B was released but instantly blocked by C...

prompt and that is where we are now...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值