【简单总结】数据库的锁

数据库的锁

曾经作为一名寻找研发实习岗的学生,被面试官问到锁相关概念时,总是一头雾水,上网查阅资料又发现各种概念,各种解释鱼龙混杂。实在是难分真伪,一直没有搞清楚。这篇博客写一下我对常听到的锁的概念的理解。
包括:乐观锁和悲观锁,共享锁和排他锁,行锁,表锁,意向锁。

乐观锁和悲观锁

所以所谓的乐观锁,其实不是数据库提供的,而是开发人员自己通过逻辑来实现的。
举个例子:可以对每个数据增加一个相应的版本号字段,读取数据的时候同时读取当时的版本号,修改返回时,再次读取版本号,判断此时版本号和之前读的时候的版本号是否一致,如果一致则修改,否则表示期间有其他进程修改了该数据,撤回这次操作。
而悲观锁,表示数据库对用户的能力表示担忧,所以提供了锁机制,悲观锁分为共享锁和排他锁。

共享锁和排他锁

这是每个数据库都会提供的两种锁机制。但是这里的两种锁依然停留在概念,或者说是理论高度,还没落实到具体的实现上。落实的实现上,根据被锁数据类型,又分为表级别的共享/排他锁(被锁住的是整个表),行级别的共享/排他锁(被锁住的是某些行)。

  • 共享锁(S): 可以共享的锁。显然,只有”读-读“操作不会产生冲突,从而可以”共享“。所以共享锁是在读操作时,可以添加的一种锁,有了这种锁,其他事务可以共享的去读这个数据,但是不能写这个数据。换句话说,可以select 但是不能update,delete等。
  • 排他锁(X):加上这个锁,任何其他事务访问被锁上的数据都会进入等待状态(等待这个X锁被释放)。

表锁和行锁

根据上面的说法,表锁和行锁都是“悲观锁”,而且表锁和行锁都分为共享锁和排他锁。只是级别不同而已,不同数据库引擎对表锁和行锁的实现情况是不同的,比如Mysql有MyISAM引擎和InnoDB引擎两种,MyISAM只支持表锁但不支持行锁,而InnoDB就支持行锁。不难理解,支持行锁的InnoDB拥有更高的并发能力,但也更容易出现所谓的死锁情况。

Mysql中锁的体现

从SQL标准来看,Mysql以及大多数数据库,select语句默认不添加任何锁,update, delete, insert语句默认添加排他锁。 select语句可以通过for update添加排他锁,通过 lock in share mode 添加共享锁。具体语法可以根据关键字自行百度。

意向锁

意向锁,是数据库额外实现,对用户透明的锁,所谓“透明”,就是看不见的意思。就是说用户不需要知道意向锁的存在。话虽这么说,但我们还是需要了解一下。
以InnoDB为例,它同时支持行锁和表锁。 当一个事务要锁整张表(以排他锁为例),那么上锁的前提是没有任何其他事务锁住这张表的任何一行。这时候事务 B得一行一行的去检查该表的每一行是否被锁住,这样效率很低,而意向锁的作用就是减少这种判断的开销。
所以意向锁的作用就是:提高效率!
具体做法,如果一个数据要添加共享锁S,那么它必须先获得IS锁,如果要添加X锁,必须先获得IX锁。这样不需要遍历每一行,只需要判断想要获得的锁是否与IS/IX锁冲突就好了。
以刚才的例子,事务A想对表A上X锁,但是另一个事务B在这个表的某些行已经上了行锁S,按照规定,事务B现在应该同时拥有该表的IS锁。这时事务A不需要一行一行的去判断,只需要判断自己相加的X锁与当前的IS锁是冲突的,进入等待状态,就是这样。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值