下一篇:共享锁
学习电子书:https://docs.oracle.com/cd/E18283_01/server.112/e16508/consist.htm#CNCPT1339
什么是排它锁?
每一个事务在修改资源时会获得排他锁,该事务不结束,则其他事务不能修改此资源。(注意:这里的修改不是数据“增删查改”中的改。数据是资源的一种,可以先理解为修改数据。第一个事务修改资源,第一个事务就先占有排他锁)。
什么是行级排他锁?
针对行数据修改,事务占有的排他锁,称作行级排它锁(或排他的行锁,或粒度为行的排它锁)。行数据修改的修改不是指数据内容的修改,它是指新增行,删除行,修改行内容。
实战:
这里有一个bank表,主键是id。下面的部分例子以当前存在的id=2的行进行说明。
第一种行修改:某一个事务删除行,其他事务不能新增该行,修改该行内容,删除该行。
打开一个窗口,针对id=2的行,执行删除操作,不commit也不rollback。(一个窗口就是一个事务)
打开另一个窗口,单独执行下面每一条语句,你会发现它都在Executing。
update bank set money = 8000 where id=2;
insert into bank values (2,8000); --主键一样
delete from bank b where b.id=2;
第二种行修改:某事务新增一行数据,另外的事务新增主键相同的行,则会等待排它锁的释放。
一个窗口执行 insert into bank values (900,8000)。另一个窗口单独执行下面的每一句sql。(每重新自测一句SQL,都要把当前事务结束掉再重新开始。)
--以下的新增操作需要等待
delete from bank b where b.id=900; -- 0条删除,原本表里就没有这条记录
update bank set money = 8000 where id=900; --0条修改,原本表里就没有这条记录
--Executing,因为可以Commit意味着就要成功插入,
--但另外的事务也加了相同主键的行,所以会等跟自己冲突的那行的排它锁释放。
insert into bank values (900,8000);
第三种行修改:某事务修改一行数据,另外的事务修改、删除相同的行,则会等待排他锁的释放。
--另一个事务修改id为2的数据 update bank b set money=900 where b.id=2
update bank set money = 8000 where id=2; --等待
delete from bank b where b.id=2; --等待
insert into bank values (2,8000); --不等待,因为另外的事务update不了主键,而新增就判断约束是否重复。