oracle中的锁概述-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 1774475
  • 博文数量: 413
  • 博客积分: 8399
  • 博客等级: 中将
  • 技术积分: 4325
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-09 10:44
文章分类

全部博文(413)

文章存档

2015年(1)

2014年(18)

2013年(39)

2012年(163)

2011年(192)

相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: oracle

2012-10-27 10:26:47

1. oracle锁的类型:
1)latch: 保护memory structure,典型的就是内存中的chain/list等结构;
2)lock: 保护database object,比如表、索引等等。分为排它锁(x); 共享锁(s)

2. 行级锁:dml语句修改行时,对该行产生行级锁;
   同时,dml语句所在的事务,产生一个事务锁tx;
   同时,行级锁会对所在表产生一个tm(table manager)表级锁rx(row exclusive);
tm: 即table manager,表级锁的总称。
tx: 即transaction exclusive,事务锁,每一个事务对应一个事务锁。可能对应多个表级的rx锁。
rx: 即row exclusive,行级排它锁,是一种tm锁,由行级锁产生在表级别上的锁。因为如果dml语句仅仅只有行级锁,在表上没有锁,会存在问题,比如当一个session在表a上进行dml语句,另一个session来drop表a,这种情况下导致问题。所以dml语句也需要在表级别上加上一个rx锁,防止表被另一个session删除掉了

3. 表级锁
1)行级排他锁(row exclusive)rx锁
   当我们进行dml时,会自动在被更新的表上添加rx锁,可以执行lock命令显式的在表上添加rx锁
   允许其他事务通过dml语句修改相同表里的其他数据行
   允许使用lock命令对表添加rx锁定
   不允许其他事务对表添加x锁
   行级共享锁(row shared,简称rs锁
select … from for update
   共享锁(share,简称s锁)
通过lock table in share mode命令添加该s锁
   排他锁(exclusive,简称x锁
通过lock table in exclusive mode命令添加x锁
   共享行级排他锁(share row exclusive,简称srx锁
       通过lock table in share row exclusive mode命令添加srx锁
   lock table  in [row share][row exclusive][share][share row exclusive][exclusive] mode;
表级锁,我们一般只关注 rx 和 rs 以及 x锁,rx由dml语句产生,rs由select for update产生,而x锁一般有ddl语句产生
另一个重要的锁是s锁:由create index语句引起。一个问题是:create index在表上加的s锁,和dml语句的rx锁是不兼容的!!!因为显然我们在进行dml操作时,是不能建立索引的。所以create index语句的运行会阻塞表上的所有dml语句。在高负载的系统上应该慎重的运行create index语句。

4. 锁的兼容性:
加锁语句
可见:
select语句没有锁,不会排斥任何其它锁;
dml语句在表上产生rx锁;
select for update在表上产生rs锁;
rs和rs之间,rx和rx之间,以及rs和rx之间都是兼容;
rs和rx在与s和srx的兼容性上有一些区别。
          
5. 锁相关的视图
1)v$lock
记录了session已经获得的锁定以及正在请求的锁定的信息
sid说明session的id号
type说明锁定锁定级别,主要关注tx和tm
lmode说明已经获得的锁定的模式,以数字编码表示
request说明正在请求的锁定的模式,以数字编码表示
block说明是否阻止了其他用户获得锁定,大于0说明是,等于0说明否

开始一个事务:
sql> delete from test_index where object_id=2;
1 row deleted.

sql> select xidusn,xidslot,xidsqn,status from v$transaction;
    xidusn    xidslot     xidsqn status
---------- ---------- ---------- ----------------
         5         25        545 active

事务产生的锁:
sql> select sid from v$mystat where rownum=1;
       sid
----------
       123
sql> select sid,type,id1,id2,
decode(lmode,0,'none',1,'null',2,'row share',3,'row exclusive',4,'share',5,'share row exclusive',6,'exclusive') lock_mode,
  decode(request,0,'none',1,'null',2,'row share',3,'row exclusive',4,'share',5,'share row exclusive',6,'exclusive')
request_mode,block
from v$lock where sid=123;

       sid ty        id1        id2 lock_mode           request_mode             block
---------- -- ---------- ---------- ------------------- ------------------- ----------
       123 tm      52516          0 row exclusive       none                         0
       123 tx     327705        545 exclusive           none                         0

结果显示:该session 123产生了两个锁:一个事务锁tx,一个表级锁tm,tm由dml语句产生。
id1:表示tm锁的对象的object_id:
sql> select object_name from dba_objects where object_id=52516;
object_name
-----------
test_index
lock_mode:表示锁的模式;
request_mode:表示是请求其它模式的锁;
block:是否阻塞了其它的事务;

对于tm锁来说,id1表示被锁定的对象的对象id,id2始终为0
对于tx锁来说,id1表示事务使用的回滚段编号以及在事务表中对应的记录编号,id2表示该记录编号被重用的次数

将tx锁的id1拆解:
sql> select trunc(327705/power(2,16)) as undo_blk#,bitand(327705,to_number('ffff','xxxx')) 0 as slot# from dual;
 undo_blk#      slot#
---------- ----------
         5         25

这个结果与select xidusn,xidslot,xidsqn,status from v$transaction;的结果是一致的。

2)v$enqueue_lock
查询v$enqueue_lock来获得锁定队列中的session信息
查询出哪些session在申请锁:
select sid,type,decode(request,0,'none',1,'null',2,'row share',3,'row exclusive',4,'share',5,'share row exclusive',6,'exclusive') request_mode from v$enqueue_lock
where sid in(131,153);

3)v$locked_object
记录了当前已经被锁定的对象的信息。

6. 系统允许的事务数量和tm锁的数量:
可以获得的tx锁定的总个数由初始化参数transactions决定,而可以获得的tm锁定的个数则由初始化参数dml_locks决定
sql> select name,value from v$parameter where name in('transactions','dml_locks');
name         value
------------ ------------
dml_locks    748
transactions 187

sql> select resource_name as "r_n",current_utilization as "c_u",max_utilization as "m_u",initial_allocation as "i_u" from v$resource_limit where resource_name in('transactions','dml_locks');

r_n                                   c_u        m_u i_u
------------------------------ ---------- ---------- --------------------
dml_locks                               1         50        748
transactions                            1         20        187

7. 死锁
在oracle数据库中,造成死锁的那个dml语句会被撤销。死锁总是由于应用程序设计不合理引起的。
当某个session的事务引起了死锁时,oracle会自动将阻塞该事务的其他事务中相应的dml语句撤销,而阻塞该事务的其他事务中的其他dml语句并没有撤销。
死锁产生示例:
session 1
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||'a' where employee_id=100

session 2
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||'b' where employee_id=101;

session 1
update employees set last_name=last_name||'c' where employee_id=101;

session 2
update employees set last_name=last_name||'d' where employee_id=100;
阅读(9038) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图