• 暂时停更一段时间!
  • 近期网站将陆续进行前端页面改造!
  • 招募网站编辑,联系站长!

数据库的锁机制

文章目录[隐藏]

锁机制

MySQL 为了解决并发、数据安全的问题 ,使用了锁机制 。

可以按照锁的粒度把数据库锁分为表级锁和行级锁。

表级锁:

MySQL 中锁定粒度最大的一种锁,对当前操作的整张表加锁, 实现简单,资源消耗较少, 加锁快 ,不会出现死锁。 其锁定粒度最大 , 触发锁冲突的概率最高,并发度最低 。 MyISAM 和 InnoDB 引擎都支持表级锁。

行级锁:

MySQL 中锁定粒度最小的一种锁,只针对当前操作的行进行加锁。 行级锁能大大减少数据库操作的冲突 。 其加锁粒度最小,并发度高,但加锁的开销也最大, 加锁慢, 会出现死锁 。

InnoDB 支持的行级锁,包括如下这几种 。

Record Lock: 对索引项加锁,锁定符合条件的行 。 其他事务不能修改和删除加锁项 。

Gap Lock : 对索引项之间的“间隙”加锁,锁定记录的范围(对第一条记录前的间隙或最后一条记录后的间隙加锁),不包含索引项本身 。 其他事务不能在锁范围内插入数据,这样就防止了别的事务新增幻影行 。

Next-key Lock : 锁定索引项本身和索引范围 。 即 Record Lock 矛 ll Gap Lock 的结合,可解决幻读问题。

虽然使用行级锁具有粒度小、并发度高等优点,但是表级锁有时候也是有必要的 :

1、事务更新大表中的大部分数据直接使用表级锁效率会更高 。

2、事务比较复杂,使用行级锁很可能引起死锁导致回滚 。

表级锁和行级锁可进一步划分为共享锁和排他锁,分别介绍如下 :

共享锁( s ):

又被称为读锁,是读取操作创建的锁 。 其他用户可以读取数据,可以再加共享锁,读取到的数据也是同一版本的;但任何事务都不能获取数据上的排他锁,不能对数据进行修改 。 获取共享锁的事务只能读取数据而不能修改数据 。 可以使用 SELECT … LOCK IN SHARE MODE;来强制获取共享锁,否则绝大部分查询操作是不会获取锁的(串行事务级别除外) 。

排他锁( x ):

又被称为写锁 , 一个事务对数据加上排他锁后,其他事务不能再对此数据加任何其他类型的锁。 获取排他锁的事务既能读取数据也能修改数据 。InnoDB 对 CUD (insert 、 update 、 delete )操作涉及的数据会默认加排他锁 。 对于查询语句可以使用 SELECT … FOR UPDATE 加排他锁 。

InnoDB 中还有如下两个表级锁。

意向共享锁( IS ):

表示事务准备给数据行加入共享锁,事务在一个数据行加共享锁前必须先取得该表的 IS 锁。

意向排他锁( IX ):

表示事务准备给数据行加入排他锁, 事务在一个数据行加排他锁前必须先取得该表的 IX 锁。

这里的意向锁是表级锁,表示的是一种意向,仅仅表示事务正在读或写某一行记录,在真正加行级锁时才会判断是否冲突 。 意向锁是 InnoDB 自动加的,不需要用户干预 。

当一个事务请求的锁模式与当前的锁兼容, InnoDB 就将请求的锁授予该事务;反之如果请求不兼容, 则该事务就等待锁释放 。

需要注意的是, InnoDB 的行级锁是基于索引实现的,如果查询语句未命中任何索引,那么 InnoDB 会使用表级锁。

此外, InnoDB 行级锁是针对索引加的锁,不针对数据记录,因此即使访问不同行的记录,如果使用到了相同的索引键仍然会出现锁冲突 。

还需要注意的是,在通过 SELECT . . . LOCK IN S HARE MODE ;或者 SELECT … FOR UPDATE 使用锁的时候,如果表没有定义任何索引,那么 InnoDB 会创建一个隐藏的聚簇索引并使用这个索引来加记录锁。

此外,不同于 MyISAM 总是一次性获得所需的全部锁 , InnoDB 的锁是逐步获得的。

当两个事务都需要获得对方持有的锁,导致双方都在等待,这时就产生了死锁。

发生死锁后,InnoDB 一般都可以检测到,并使一个事务释放锁回退,另一个则可以获取锁完成事务 。

可以采取以下的方式避免死锁

通过表级锁来减少死锁产生的概率 。

多个程序尽量约定以相同的顺序访问表(这也是解决并发理论哲学家就餐问题的一种思路)

同一个事务尽可能做到一次锁定所需要的所有资源


丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:数据库的锁机制
喜欢 (0)
[247507792@qq.com]
分享 (0)
多啦H梦
关于作者:
热爱开源,热爱分享,谢谢大家的资瓷!

邀请您免费 注册账号 登录 即可参与讨论!

(1)个小伙伴在吐槽
  1. 总结的不错
    21962014722018-08-19 22:30 Windows 10 | Firefox浏览器 61.0