数据库中的锁

【全局锁】

数据库中的表只能读取,不能增删改

--加锁--
flush table with read lock;

--解锁--
unlock tables;

 

【共享锁 Shared lock】

也称读锁。不阻塞其他事物的读操作,但阻塞写操作

当Session1对数据A添加共享锁之后,可读不可写。Session2可以继续添加共享锁。都能读取数据A,

但在A上的共享锁释放前,无法进行写操作。因为写操作需要对数据添加排他锁,而数据库不允许共享锁和排他锁同时存在

 

i   会产生死锁

[死锁]

示例:

有两个事务同时进行:(同时添加共享锁再修改)

这里的holdlock表示将一直保持共享锁到事务结束。

begin transaction t1
select * from Commodity with (holdlock)     --添加保持锁
update Commodity set Title='holdlock test'

begin transaction t2
select * from Commodity
update Commodity set Title='holdlock test02'

分析:

由于同时进行,两个事务同时对数据加了共享锁(允许加锁)。此时要想继续进行修改操作的话,就必须加排他锁,所以必须等其他事务的共享锁释放

那么两个事务形成了循环等待,形成了死锁。

 

ii   也可能造成等待

比如

同时对数据进行修改:

session1   :  update Commodity set Title='holdlock test' where Id=4

session1   :  update Commodity set Title='holdlock test' where Id=4

分为两种情况

1.如果Title添加了索引,则两次修改都会直接定位到Id=4这行数据,加排他锁。互不影响。

2.如果没加:Session1进行全表扫描,找到后加排他锁修改。Session1全表扫描需要 为全表 加 共享锁 /更新锁/ 排他锁,都要先等Session1释放排他锁,不然无法为全表加锁

 

死锁可以通过提升隔离级别来解决,即将隔离级别设置成Serializable 串行读。

 

【更新锁  Update lock】

更新锁与共享锁兼容。防止上诉的死锁情况。更新锁会阻塞其他更新锁和排他锁。

更新锁允许其他事务在更新之前读取数据,但不可以修改。想获取排他锁,必须等更新锁释放。

Session1中找到需要更新的数据,更新锁直接转换成排他锁

共享锁之间是兼容的,可以有多个共享锁,但是更新锁之间是不兼容的。只有一个更新锁转化为排他锁是安全的。

所以,在上面我们知道,共享锁转化成排他锁(修改数据)时,需要等待其他共享锁释放(死锁原因)。

因为共享锁可以有很多个,而排他锁只能有一个,所以共享锁不能全部转化成排他锁,必须等其他共享锁释放。

更新锁只能有一个,所以直接转化成排他锁是安全的。

 示例:

添加更新锁

begin transaction t1
select * from Commodity with (updlock)     --添加更新锁
update Commodity set Title='holdlock test'

此时查询

begin transaction t2
select * from Commodity 
update Commodity set Title='holdlock test'

 

这里分为2种情况:

1.事务t1先到:先对Commodity表添加了更新锁,事务t2此时也可以查询,因为共享锁和更新锁兼容。而事务t2想更新数据是不允许的,因为它需要获取排他锁,

而数据已经有了更新锁,会阻塞排他锁。需要等事务t1更新完数据(更新锁转排他锁),释放了排他锁,事务t2才能更新。

 

2.事务t2先到达:也是同理。因为t1一旦声明了更新锁。其他事务将不能更新。依然会是上诉流程。

 

 

【排他锁】

也叫写锁。阻塞任何锁。包括读写锁。

 

【行锁】对叶子节点对应记录上锁,防止其他事务对其删改

【间隙锁】对叶子节点之间的间隙上锁,防止其他事务在这个间隙insert,确保索引记录间隙不变;

【临建锁】行锁和间隙锁的组合,锁住数据也锁住间隙。

 

posted @   RookieCoderAdu  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示