锁系列二之读写锁

 从数据操作的类型划分

对于 InnoDB 引擎来说,读锁和写锁可以加在表上,也可以加在行上。

一、读锁

也称为 共享锁 、英文用 S 表示。针对同一份数据,多个事务的读操作可以同时进行而不会互相影响,相互不阻塞的。

二、写锁

也称为 排他锁 、英文用 X 表示。当前写操作没有完成前,它会阻断其他写锁和读锁。这样就能确保在给定的时间里,只有一个事务能执行写入,并防止其他用户读取正在写入的同一资源。

1、锁定读

在采用加锁方式解决脏读,不可重复读,幻读 这些问题的时候,读取一条记录时需要获取该记录的s锁,有的时候需要在读取记录的时候获取记录的x锁,来禁止别的事务读取该记录,此时mysql提供了两种比较特殊的select语句格式

(1)对读取的记录加s锁

 在普通的select语句后加上Lock in share mode,如果当前事务执行了该语句,那么它会为读取到的记录加s锁,这样允许别的事务继续获取这些记录的s锁(别的事务也使用select ... Lock in share mode语句来读取这些记录),但是不能获取这些记录的x锁(比如使用select ... for update语句来读取这些记录,或者直接修改这些记录)如果别的事务想要获取这些记录的x锁,那么他们会阻塞,直到当前事务提交后将这些记录上的s锁释放掉。

(2)对读取的记录加x锁

在普通的select语句后加for update 如果当前事务执行该语句,那么它会为读取到的记录加x锁,这样既不允许别的事务来获取这些记录的s锁(比如使用select ... Lock in share mode来读取这些记录)也不允许获取这些记录的x锁,如果别的事务想要获取这些记录的s锁或者x锁,那么它们会阻塞,直到当前事务提交后将这些记录的上的x锁释放掉。

mysql8.0新特性

在5.7及之前的版本,select ... for update,如果获取不到锁,会一直等待,直到innodb_lock_wait_timeout超时,在8.0版本中,select ... for update,select ... for share 添加了nowait(当获取不到锁则立刻返回),skip locked(只返回结果中不包含被锁住的行)

案例:

(1)两个事务都是加共享锁(不阻塞

事务1:

事务2:

 (2)一个事务加共享锁,一个事务加排他锁(会阻塞

事务1先加共享锁,事务2后加排他锁

事务1先加排他锁,事务2后加共享锁

(3)8.0新特性

事务1加排他锁

 事务2使用8.0新特性

2、写操作

(1)delete

对一条记录做delete操作的过程,在B+树中定位到这条记录的位置,然后获取这条记录的x锁,再执行delete mark操作。可以把这个定位待删除记录在B+树中位置的过程看成是一个获取x锁的锁定读。

(2)update

        1)情况1,在未修改该记录的键值,并且被更新的列占用的存储空间在修改前后未发生变化。则在B+树中定位到这条消息的位置,然后再获取该记录的x锁,最后在原记录的位置进行修改操作。可以把定位待修改记录在B+树中的位置的过程看成是获取X锁的锁定读。

        2)情况2,未修改该记录的键值,并且至少有一个被更新的列占用的存储空间在修改前后发生变化。则在B+树中定位到该记录的位置,然后获取该记录的x锁,将该记录彻底删除掉(就是把记录彻底移入垃圾链表),最后再插入一条新记录。这个定位待修改记录在B+树中位置的过程可以看成是一个获取X锁的锁定读,新插入的记录由insert操作提供隐式锁进行保护。

        3)情况3,修改了该记录的键值,则相当于在原记录上做delete操作之后再来一次insert操作,加锁操作就需要按照delete和insert规则进行。

 (3)insert

一般情况下,新插入的记录是不用加锁的,通过一种称之为隐式锁的结构来保护这条记录的在本次事务提交前不被别的事务访问。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值