1、Oracle锁类型
锁的作用:保护数据、并发(Oracle 可以并发,因为有锁;因为有锁,限制并发)
latch锁:chain,链,保护chain(用于oracle内部)
LOCK锁:保护数据(用于用户数据),最小的粒度单位是行
排他锁(X)
共享锁(S)
ORACLE特点:Oracle对行的修改,不影响另外一个事物对这个行的读,ORALCE并发好的原因。
2、行级锁:DML语句
行级锁--》事物锁
事务锁TX
事务锁的加锁和解锁过程
DML语句
commit,rollback
只有排他锁
不影响读(CR块)
3、表级锁:TM
行级排他锁(Row exclusive)RX锁
当我们进行DML时,会自动在被更新的表上添加RX锁,可以执行LOCK命令显式的在表上添加RX锁
允许其他事务通过DML语句修改相同表里的其他数据行
允许使用lock命令对表添加RX锁定
不允许其他事务对表添加X锁
行级共享锁(Row Shared,简称RS锁)
共享锁(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锁
locktable in [row share][rowexclusive][share][share row exclusive][exclusive] mode;
Select * from normal_t for update;
注意:网络上许多资料这个语句说产生RS锁,是错误的,正确的是RX锁
lock table normal_t in row share mode;
locktable normal_t in row exclusive mode;
locktable normal_t in share mode;
locktable normal_t in share row exclusive mode;
locktable normal_t in exclusive mode;
FROM v$locked_object a,dba_objects b
WHERE a.OBJECT_ID = b.OBJECT_ID;
normal_t set object_name='wzx' where object_id=100;
4、锁的兼容性
5、加锁语句以及锁的释放
6、锁相关视图
v$transaction
XIDUSN表示当前事务使用的回滚段的编号
XIDSLOT说明该事务在回滚段头部的事务表中对应的记录编号(也可以叫做槽号)
XIDSQN说明序列号
STATUS说明该事务是否为活动的
v$lock
记录了session已经获得的锁定以及正在请求的锁定的信息
SID说明session的ID号
TYPE说明锁定锁定级别,主要关注TX和TM
LMODE说明已经获得的锁定的模式,以数字编码表示
REQUEST说明正在请求的锁定的模式,以数字编码表示
BLOCK说明是否阻止了其他用户获得锁定,大于0说明是,等于0说明否
锁定模式 锁定简称 编码数值
RowExclusive RX 3
RowShared RS 2
Share S 4
Exclusive X 6
ShareRow Exclusive SRX 5
NULL N/A 0或者1
该视图中包含的字段以及字段含义与v$lock中的字段一模一样。
只不过该视图中只显示那些申请锁定,但是无法获得锁定的session信息。
其中的记录按照申请锁定的时间先后顺序排列,先申请锁定的session排在前面,排在前面的session将会先获得锁定。
v$locked_object
记录了当前已经被锁定的对象的信息
XIDUSN表示当前事务使用的回滚段的编号
XIDSLOT说明该事务在回滚段头部的事务表中对应的记录编号
XIDSQN说明序列号
OBJECT_ID说明当前被锁定的对象的ID号,可以根据该ID号到dba_objects里查找被锁定的对象名称
LOCKED_MODE说明锁定模式的数字编码
v$session
记录了当前session的相关信息
SID表示session的编号
SERIAL#表示序列号
SID和SERIAL#可以认为是v$session的主键,它们共同唯一标识一个session
grantselect on v_$mystat to weisi;
selectsid from v$mystat where rownum=1;
updatenormal_t set object_name='wzx' where object_id=100;
select* from v$lock where block=1;
--查看数据库有没有事物
xidusn,xidslot,xidsqn,status from v$transaction;
--查看某会话已经获取和请求的锁
select sid from v$mystat where rownum=1;
select sid,type,id1,id2,
decode(lmode,0,'None',1,'Null',2,'Row share',3,'RowExclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_mode,
decode(request,0,'None',1,'Null',2,'Rowshare',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')
request_mode,block
from v$lock
wheresid=145;
selectowner,object_name from dba_objects where object_id=74755;
对于TM锁来说,ID1表示被锁定的对象的对象ID,ID2始终为0
对于TX锁来说,ID1表示事务使用的回滚段编号以及在事务表中对应的记录编号,ID2表示该记录编号被重用的次数(wrap)
selectxidusn,xidslot,xidsqn,status from v$transaction;
将ID1拆解
selecttrunc(327680/power(2,16)) as undo_blk#,bitand(327680,to_number('ffff','xxxx'))+ 0 as slot# from dual;
select sid from v$mystat where rownum=1;
selectsid from v$mystat where rownum=1;
查询v$enqueue_lock来获得锁定队列中的session信息
selectsid,type,
decode(request,0,'None',1,'Null',2,'Rowshare',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')
request_mode
fromv$enqueue_lock
wheresid in(145,150);
--查询那些会话锁住,影响到哪些会话
select a.sidblocker_sid,a.serial#,a.username as blocker_username,b.type,
decode(b.lmode,0,'None',1,'Null',2,'Rowshare',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')lock_mode,
b.ctime as time_held,c.sid aswaiter_sid,
decode(c.request,0,'None',1,'Null',2,'Rowshare',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(+) andc.type(+) = 'TX' and b.type = 'TX'and b.block = 1
order by time_held, time_waited;
alter system kill session'150,182';
一个事务修改多行,产生一个TX锁
select sid from v$mystat where rownum=1;
updatenormal_t set object_name='wzx' where object_id=101;
updatenormal_t set object_name='wzx' where object_id=102;
updatenormal_t set object_name='wzx' where object_id=103;
select sid,type,id1,id2,
decode(lmode,0,'None',1,'Null',2,'Rowshare',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')lock_mode,
decode(request,0,'None',1,'Null',2,'Rowshare',3,'Row Exclusive',4,'Share',5,'Share RowExclusive',6,'Exclusive')request_mode,block
from v$lock
where sid=150;
可以获得的TX锁定的总个数由初始化参数transactions决定,而可以获得的TM锁定的个数则由初始化参数dml_locks决定
select name,value fromv$parameter where name in('transactions','dml_locks');
--查看当前数据库TM锁和TX锁数目和目前位置最大的数目和初始化数目
fromv$resource_limit
whereresource_name in('transactions','dml_locks');
死锁
两个session(以A和C来表示),如果A持有C正在申请的锁定,同时C也持有A正在申请的锁定时,这时发生死锁现象。死锁是典型的“双输”情况,如果任其发展,则会出现A和C这两个session正在执行的事务都无法结束的现象。因此,在Oracle数据库中,造成死锁的那个DML语句会被撤销。死锁总是由于应用程序设计不合理引起的。
当某个session的事务引起了死锁时,Oracle会自动将阻塞该事务的其他事务中相应的DML语句撤销,而阻塞该事务的其他事务中的其他DML语句并没有撤销。
session 1
select sid from v$mystat where rownum=1;
update t set object_name='weisi' whereobject_id=202
session 2
select sid from v$mystat where rownum=1;
update t set object_name='weisi' whereobject_id=201
update t set object_name='weisi' where object_id=201
session2
update t set object_name='weisi' whereobject_id=202
网友评论