Oracle数据库锁机制实践

为了解决数据库被并发事物访问所带来的问题,数据库提供了锁机制来应对。数据库锁根据锁定的对象不同,可以分为表级锁和行级锁,表级锁锁定的对象是整张表,行级锁锁定的对象是特定的数据行;根据锁之间的关系可以分为共享锁和独占锁,共享锁允许其他事物获取共享锁,但是不予许其他事物获取独占锁。独占锁既不允许其他事物获取共享锁,又不允许其他事物获取独占锁。 

行级锁:insert 、update、 delte 和 select…for update等都会隐士的获取一个行级锁。 

表级锁:lock table tableName in shre mode 或 lock tabletableName in exclusive mode的获取一个表级锁。

共享锁:共享锁只支持表级锁,没有行级别的。通过lock table tableName in shre mode 添加。

独占锁:所有的行级锁都是独占锁。Lock table tableName inexlusive mode对整张表获取独占锁。

 

共享锁的行为:每个事物的共享锁都防止其他事物的独占锁,但是自己的共享锁不妨自己的独占锁。如果事物A独自获取了表T的共享锁,那么事物A还可以获取表T上的独占锁;如果事物A获取了表T的共享锁,事物B也获取了表T的共享锁,那么此时事物A不能获取T的独占锁了,因为事物B的共享锁不允许。

事物A:locktable tt_stu insharemode;

事物A进行如下操作会成功:insertinto tt_stu values(4,'a')

deletefrom tt_stu whereid=3;

update tt_stu setname='llll0l'whereid=1;

SELECT * FROM tt_stu whereid=2forupdate;

这四个操作都需要独占锁,因为只有自己持有共享锁,同一个事物的共享锁允许自己的独占锁。反过来自己的独占锁也不会排斥自己的共享锁,也就是自己不排斥自己。

如果上述情况,事物A在进行增删改查之前,事物B也执行了locktable tt_stu insharemode;则后四个操作会被阻塞,直到事物B提交了事物释放了共享锁。

如果上述情况,事物A执行了insert语句,则此时事物B去执行locktable tt_stu insharemode;事物B会被阻塞,因为事物A不仅有表上的共享锁,insert会隐式添加一个独占锁,阻止了事物B的共享锁。

 

独占锁的行为:每个事物的独占锁,都防止其他事物的共享锁和独占锁,允许自身事物的共享锁和独占锁。

事物A:locktable tt_stu inexclusivemode;

事物A进行如下操作都会成功:insertinto tt_stu values(4,'a');

deletefrom tt_stu whereid=2;

update tt_stu setname='llll0l'whereid=2 ;

SELECT * FROM tt_stu whereid=2forupdate;

locktable tt_stu insharemode;


因为他们在同一个事物,所以没影响。

行级独占锁和表级独占锁有区别:事物A执行:locktable tt_stu inexclusivemode;这是表独占锁,事物B无法获取该表的共享锁、及任意行的独占锁(也就是意味事物B无法进行增、删、改以及select…for update)。

如果事物A执行:SELECT * FROM tt_stu whereid=2forupdate;仅仅对id=2的数据行添加锁,事物B无法对id=2的数据行添加独占锁以及不能添加共享锁(因为共享锁只能是表级锁,包括id=2的行),但是事物B可以对其他数据行添加独占锁(可以对其他数据行进行修改删除以及执行insert)。

如果事物A执行:insertinto tt_stu values(4,'a');id=4的数据行获取独占锁,事物B无法获取共享锁以及表独占锁(不可以执行locktable tt_stu insharemodelocktable tt_stu inexclusivemode),但是可以执行任意行独占锁(可以执行任意行insertupdatedelteselect for update )。


PS: 普通的select语句无视锁的存在,锁对其没限制。

Oracle5种表级锁:之前已经使用过了2种表级锁,表共享锁和表独占锁,以及行共享表级锁、行独占表级锁和表共享行独占表级锁。下图给出了表锁与表锁、dmlddl的关系。

关系图(此处dml仅指增删改及select  for update)

 

表共享lock table tableNamein share mode;允许其他Session的表共享和行共享表级锁。阻止其他Session dmlselect for update语句。

表独占lock table tableNamein exclusive mode;阻止一切锁。阻止其他sessiondml select for update语句。

行共享表级锁select  for update隐式添加,lock table tableName in row share mode;显式添加。仅允许其他Session获取行共享表级锁、行独占表级锁、表共享和表共享行独占表级锁。允许其他SessionDMLSelect for update.

行独占表级锁dml操作隐式添加,lock table tableName in row exclusivemode 显式添加。仅允许其他Session获取行共享表级锁和行独占表级锁。允许其他SessionDMLSelect for update

表共享行独占锁lock table in sharerow exclusive mode;添加。仅允许其他Session获取行共享表级锁。阻止其他Session dmlselect for update语句。

表共享和表独占2种表级锁与行级锁的互斥关系可以用共享锁独占锁分析,也可遵守上图与Dml语句的关系(因为dml除了select都会加行级锁,select for update也会),但是后面3种表级锁与行级锁的关系,只能遵守上图分析,不能直接根据共享锁和独占锁关系判断。

举例:

情况一:

A locktable tt_stu inrowexclusivemode;行共享表级锁

B locktable tt_stu insharerowexclusivemode;表共享行独站表级锁,AB不冲突。

情况二:

A SELECT * FROM tt_stu whereid=2forupdate;行共享表级锁(同情况一)

B locktable tt_stu insharerowexclusivemode;表共享行独站表级锁,AB产生冲突,因为表共享行独占锁会阻塞(ddl操作,和ddl互斥)。

要判断一个表级锁是否会阻塞另外一个表级锁,不仅要看表里的锁兼容性,还要判断是否dml隐式加锁从而判断是否支持dml,要这2个方面都支持才兼容。

 

PS:分析锁的关系时候,既要考虑表锁上的也要考虑行锁上的兼容性。5种表锁都不允许ddl操作。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值