Oracle中的锁(LOCK)机制(二)

2014-11-24 15:37:55 · 作者: · 浏览: 7
ect)

4 and type in ('TM', 'TX')

5 order by 1 ;

SID TYPE ID1 LMODE REQUEST BLOCK

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

22 TM 82618 6 0 1 --session1 包含了表6级锁,它正在阻塞其他的事务

22 TX 524296 6 0 0

24 TM 82618 0 3 0 --session2 它正在请求表的3级锁。

Session1

Session2

Description

T1

insert /*+ append_values */ into tun2_tab values (1) ;

直接路径加载会对表加6级排他锁

T2

update tun2_tab set id=3 ;

waiting…

update需要对表加3级共享锁,因为互斥,session2陷入阻塞状态

所以在直接路径加载的时候会对表加6级锁,阻塞其他事务对表加任意类型锁的操作。

(sqlldr 并行+直接路径加载的时候会加4级锁)

因为主键|唯一键引发的阻塞

_dexter@FAKE>alter table tun2_tab add primary key (id) ;

Table altered.

session1 session_id=22:

_dexter@FAKE>insert into tun2_tab values (1) ;

1 rowcreated.

session2 session_id=24:

_dexter@FAKE>insert into tun2_tab values (1) ;

waiting...

lockstatus :

_sys@FAKE>select sid , type , id1 , lmode , request , block

2 from v$lock l

3 where sid in (select session_id from v$locked_object)

4 and type in ('TM', 'TX')

5 order by 1 ;

SID TYPE ID1 LMODE REQUEST BLOCK

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

22 TM 82618 3 0 0

22 TX 196635 6 0 1

24 TX 65548 6 0 0

24 TM 82618 3 0 0

24 TX 196635 0 4 0

_sys@FAKE>select sid,seq#,event from v$session_wait where sid= 24 ;

SID SEQ# EVENT

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

24 104 enq: TX - row lock contention

这里发生了row lock等待事件。

可以看到

因为在拥有primary key 列上插入了相同的值,第二个session除了持有自己本事务的6级排他锁之外,还在请求一个4级共享锁。这里发生了阻塞。如果第一个session 提交 。

第二个session会报错。

_dexter@FAKE>insert into tun2_tab values (1) ;

insert intotun2_tab values (1)

*

ERROR atline 1:

ORA-00001:unique constraint (DEXTER.SYS_C0014094) violated

Session1

Session2

Description

T1

insert into tun2_tab values (1) ;

session1插入数据这里涉及到了主键|唯一键

T2

insert into tun2_tab values (1) ;

waiting …

session2插入相同的记录,会发生阻塞,因为session1的操作是悬而未决的状态,session2中的事务能否执行取决于session1中的事务是回滚还是提交

T3

commit

session 1 中的事务提交

T4

Raise error:

ORA-00001: unique constraint (DEXTER.SYS_C0014094) violated

Update阻塞

这一部分的阻塞比较简单,只要发生update操作,就会对已有的行加6级排他锁,表上加3级共享锁。

_dexter@FAKE>select * from tun2_tab ;

ID NAME

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

1 NN

2 NN

3 NN

session1 session_id=22:

_dexter@FAKE>update tun2_tab set name = 'DEXTER' where id=1 ;

1 rowupdated.

session2 session_id=18:

_dexter@FAKE>update tun2_tab set name ='dexter' where id=2 ;

1 rowupdated.

session3 session_id=9:

_dexter@FAKE> update tun2_tab set name ='dexter' where id=1;

waiting...

来看一下锁的情况:

_sys@FAKE>/

SID TYPE ID1 LMODE REQUEST BLOCK

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

9 TX 589850 0 6 0

9 TM 82618 3 0 0

18 TX 196629 6 0 0

18 TM 82618 3 0 0

22 TX 589850 6 0 1 --session1正在阻塞 session 3

22 TM 82618 3 0 0

6 rowsselected.

由上可以看到,对单个表可以加多个3级共享锁

session2因为修改的是id=2 的记录,所以可以正常执行。

session3由于修改的是id=1 的记录,session1这个时候正在修改,并且对这一行的资源加了6级的排他锁。所以session3 发生了阻塞

需要等待session 1 释放后才可以顺利执行。

Session1

Session2

Session3

Description

T1

update tun2_tab set name = 'DEXTER' where id=1 ;

session1 update操作会对表加3级共享锁

T2

update tun2_tab set name ='dexter' where id=2 ;

session2 update操作 也会对表加3级共享锁,由于更新的记录不包括ssession1中更新的记录id=1。所以可以顺利执行

T3

update tun2_tab set name ='dexter' where id=1 ;

waiting…

session3 update操作 也会对表加3级共享锁,由于更新的记录包括ssession1中更新的记录id=1。所以无法顺利执行

Delete阻塞

其实对于delete、update、insert操作加锁操作大致相同,都会对表加3级共享锁,对修改的行加排他锁。