Friday, April 10, 2009

Oracle10g的锁机制

看起来,oracle的锁分为表锁和行锁两个级别(看起来比sqlserer和mysql都要少,实际上还有一些内部锁是用户看不到的,此外oracle实现并发控制主要以来multiversion,Refer to:http://www.sc.ehu.es/siwebso/KZCC/Oracle_10g_Documentacion/server.101/b10743/consist.htm)
根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(data locks,数据锁),用于保护数据的完整性;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and latches),保护数据库的内部结构。
DML锁的目的在于保证并发情况下的数据完整性,本文主要讨论DML锁。在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。
表1 Oracle的TM锁类型
锁模式 锁描述 解释 SQL操作
0 none

1 NULL Select
2 RS(Row-S) 行级共享锁,其他对象只能查询这些数据行

Select for update、Lock for update、Lock row share

3 RX(Row-X) 行级排它锁,在提交前不允许做DML操作

Insert、Update、Delete、Lock row share

4 S(Share) 共享锁 Create index、Lock share
5 SRX(S/Row-X) 共享行级排它锁 Lock share row exclusive
6 X(Exclusive) 排它锁

Alter table、Drop able、Drop index、Truncate table 、Lock exclusive



SQL Statement Mode of Table Lock Lock Modes Permitted?
RS RX S SRX X

SELECT...FROM table...

none

Y

Y

Y

Y

Y

INSERT INTO table ...

RX

Y

Y

N

N

N

UPDATE table ...

RX

Y*

Y*

N

N

N

DELETE FROM table ...

RX

Y*

Y*

N

N

N

SELECT ... FROM table FOR UPDATE OF ...

RS

Y*

Y*

Y*

Y*

N

LOCK TABLE table IN ROW SHARE MODE

RS

Y

Y

Y

Y

N

LOCK TABLE table IN ROW EXCLUSIVE MODE

RX

Y

Y

N

N

N

LOCK TABLE table IN SHARE MODE

S

Y

N

Y

N

N

LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE

SRX

Y

N

N

N

N

LOCK TABLE table IN EXCLUSIVE MODE

X

N

N

N

N

N

from: http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/consist.htm#sthref1939

select....不会在任何资源上加任何锁,默认的隔离级别是read committed,这个隔离级别下的transaction set consistency是statement-level(serializable的隔离级别下则为transactio-level)。
statement-level是指query的时候只返回query开始前的所有数据,不会返回query执行过程中对data的修改。 transaction-level这是query的时候返回事务开始前的所有的数据,不会返回事务执行过程中对data的修改。
这里说一下怎么测试oracle的锁。oracle有一些数据字典可以获得会话和锁的信息。
表2 数据字典视图说明
视图名 描述 主要字段说明
v$session 查询会话的信息和锁的信息。

sid,serial#:表示会话信息。

program:表示会话的应用程序信息。

row_wait_obj#:表示等待的对象。

和dba_objects中的object_id相对应。

v$session_wait 查询等待的会话信息。

sid:表示持有锁的会话信息。

Seconds_in_wait:表示等待持续的时间信息

Event:表示会话等待的事件。

v$lock 列出系统中的所有的锁。

Sid:表示持有锁的会话信息。

Type:表示锁的类型。值包括TM和TX等。

ID1:表示锁的对象标识。

lmode,request:表示会话等待的锁模式的信

息。用数字0-6表示,和表1相对应。

dba_locks 对v$lock的格式化视图。

Session_id:和v$lock中的Sid对应。

Lock_type:和v$lock中的type对应。

Lock_ID1: 和v$lock中的ID1对应。

Mode_held,mode_requested:和v$lock中

的lmode,request相对应。

v$locked_object 只包含DML的锁信息,包括回滚段和会话信息。

Xidusn,xidslot,xidsqn:表示回滚段信息。和

v$transaction相关联。

Object_id:表示被锁对象标识。

Session_id:表示持有锁的会话信息。

Locked_mode:表示会话等待的锁模式的信

息,和v$lock中的lmode一致。

比如,打开一个sql*plus,然后
> select * from game for update.
> select * from dba_locks;
从返回的结果集可以看到这个会话说获得的锁(可以通过select * from v$session来获得会话id)。
> commit;
commit之后会释放这个事务获得的所有的锁。

如何手动的释放锁?
--查看锁

select t2.username,t2.sid,t2.serial#,t2.logon_time
from
v$locked_object t1,v$session t2
where t1.session_id=t2.sid order by
t2.logon_time;

--alter system kill session 'sid,serial#';
--
把锁给KILL掉
alter system kill session '146,21177';

查询锁定的资源:

select * from v$locked_object; //得到被锁定的object

select * from dba_objects where object_id=?1 //根据上面查询得到的object_id。


1 comment:

Anonymous said...

Data Concurrency and Consistency: http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/consist.htm#i13945