锁相关基础知识

1. 锁类型
latch锁: 保护内存结构, chain, 链
lock 锁: 保护 buffer, block | 排他锁 (X), 共享锁 (S)

2. 行级锁
由 DML 语句产生, 数据行的所标记指向事务槽

3. 事务锁 (TX)
一个事务修改多行也之会产生一个事务锁
由行级锁产生, commit 或 rollback 解锁, 不影响读 (产生 CR 块)

4. 表级锁 (TM)
即行级排他锁 RX 锁 (Row exclusive)
当进行 DML 时, 会自动在被更新的表上添加 RX 锁, 也可以执行 lock 命令显式的在表上添加 RX 锁
允许其他事务通过 DML 语句修改相同表里的其他数据行
允许其他事务使用 lock 命令对表添加 RX 锁定
不允许其他事务对表添加 X 锁

4-1. 行级共享锁 (Row Shared, 简称 RS 锁)
select * from t for update

4-2. 共享锁 (Share, 简称 S 锁)
lock table t in share mode

4-3. 排他锁 (Exclusive, 简称 X 锁)
lock table t in exclusive mode

4-4. 共享行级排他锁 (Share Row Exclusive, 简称 SRX 锁)
lock table t in share row exclusive mode

5. 视图
5-1. v$transaction
select xid,xidusn,xidslot,xidsqn,ubafil,ubablk,status from v$transaction;

xid: 事务ID
xidusn : 表示当前事务使用的回滚段的编号 xidslot : 说明该事务在回滚段头部的事务表中对应的记录编号(也可以叫做槽号)  
xidsqn : 说明序列号
status: 说明该事务是否为活动的
ubafil: 该事务对应的最后(新)的回滚块数据文件
ubablk: 该事务对应的最后(新)的回滚块号

5-2. v$lock
记录了会话已经获得的锁定以及正在请求的锁定的信息
SID: 会话的ID号
TYPE: 锁定锁定级别
LMODE: 已经获得的锁定的模式, 以数字编码表示
REQUEST: 正在请求的锁定的模式, 以数字编码表示
BLOCK: 是否阻止了其他用户获得锁定, 大于 0 说明是, 等于 0 说明否

锁定模式                锁定简称 编码数值
Row Exclusive           RX       3
Row Shared              RS       2
Share                   S        4
Exclusive               X        6
Share Row Exclusive     SRX      5
NULL                    N/A      0 或者 1

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=159;

获取锁定与被锁定的会话
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;

对于 TM 锁来说, ID1 表示被锁定的对象的对象ID, ID2 始终为 0
对于 TX 锁来说, ID1 表示事务使用的回滚段编号以及在事务表中对应的记录编号, ID2 表示该记录编号被重用的次数
将 ID1 拆解
select trunc(393249/power(2,16)) as undo_blk#,bitand(393249,to_number('ffff','xxxx')) + 0 as slot# from dual;

5-3. v$enqueue_lock
该视图中包含的字段以及字段含义与 v$lock 中的字段一模一样
该视图中只显示那些申请锁定, 但是无法获得锁定的会话信息
记录按照申请锁定的时间先后顺序排列, 先申请锁定的会排在前面, 排在前面的会话将会先获得锁定

select a.sid blocker_sid,a.serial#,a.username as blocker_username,b.type,
decode(b.lmode,0,'None',1,'Null',2,'Row share',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_mode,
b.ctime as time_held,c.sid as waiter_sid,
decode(c.request,0,'None',1,'Null',2,'Row share',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') request_mode,
c.ctime time_waited
from v$lock b, v$enqueue_lock c, v$session a
where a.sid = b.sid and b.id1= c.id1(+) and b.id2 = c.id2(+) and c.type(+) = 'TX' and  b.type = 'TX' and b.block = 1
order by time_held, time_waited;

alter system kill session '129,10910';

5-4. v$locked_object
记录了当前已经被锁定的对象的信息
XIDUSN: 当前事务使用的回滚段的编号
XIDSLOT: 该事务在回滚段头部的事务表中对应的记录编号
XIDSQN: 序列号
OBJECT_ID: 当前被锁定的对象ID, 可以根据该 ID 号到 dba_objects 里查找被锁定的对象名称
LOCKED_MODE: 锁定模式的数字编码

select /*+ RULE */ /* ls.osuser os_user_name,*/ ls.username,ls.type,o.object_name,
decode(ls.lmode,1,null,2, 'Row Share',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive',null) lock_mode,
o.owner,ls.sid,ls.serial#,ls.id1,ls.id2
from dba_objects o,
(select s.osuser,s.username,l.type,l.lmode,s.sid,s.serial#,l.id1,l.id2 from v$session s,v$lock l where s.sid = l.sid) ls
where o.object_id = ls.id1 /* and o.owner <> 'SYS' */
order by o.owner, o.object_name;

5-5. v$session
记录了当前所有会话的相关信息
SID: 会话的编号
SERIAL#: 序列号
SID 和 SERIAL# 可以认为是 v$session 的主键, 它们共同唯一标识一个会话

6. 初始化参数
transactions: 数据库整体能执行的并行活动事务总数 (可以获得的 TX 锁定的总个数)
dml_locks: 一个表上可以同时获得的 TM 锁总数
select name,value,description from v$parameter where name in('transactions','dml_locks');

select resource_name,current_utilization,max_utilization,initial_allocation
from v$resource_limit
where resource_name in('transactions','dml_locks');

7. 死锁
在 Oracle中, 造成死锁的那个 DML 语句会被撤销, 死锁总是由于应用程序设计不合理引起的
当某个会话的事务引起了死锁时, 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;


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22558114/viewspace-1122582/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/22558114/viewspace-1122582/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值