继续深入数据库 了解一下数据库的锁机制

栏目: 数据库 · 发布时间: 7年前

内容简介:我们在高并发的场景下,经常会在异常日志中看到“dead lock(死锁)”的错误信息。想了无数的解决方案,都没有能够最终的解决,到底是什么原因引起了死锁呢?要解决这个问题,我们就必须先了解透彻数据库都有哪些锁?他们的工作机制是什么样的。那,让我们开启今天的学习之路吧。当多条请求并发访问一个数据库资源时,有可能就会导致数据的不一致,因此,就需要一种机制来将数据库的访问顺序化,从而保证数据库数据的一致性,这个我们在

我们在高并发的场景下,经常会在异常日志中看到“dead lock(死锁)”的错误信息。想了无数的解决方案,都没有能够最终的解决,到底是什么原因引起了死锁呢?要解决这个问题,我们就必须先了解透彻数据库都有哪些锁?他们的工作机制是什么样的。

那,让我们开启今天的学习之路吧。

为什么数据库要加锁?

继续深入数据库 了解一下数据库的锁机制

当多条请求并发访问一个数据库资源时,有可能就会导致数据的不一致,因此,就需要一种机制来将数据库的访问顺序化,从而保证数据库数据的一致性,这个我们在

《数据库常用的事务隔离级别都有哪些?都是什么原理?》也有讲到。事务就是就是一种顺序化的机制,而事务要达到目的,就必须要有所的支持。

继续深入数据库 了解一下数据库的锁机制

数据库都有哪些锁?

由于数据库的种类也不少,每种数据库的锁大致都相同,但是细节上略有不同,因此,我们就选择MySql/InnoDB作为讲解的对象。

InnoDB按照锁的类型来划分,主要分为了三个大类:共享锁(Shared lock)、排它锁,也叫独占锁(Exclusive Locks)、意向锁(Intent Locks)。其中,意向锁又分为了意向共享和意向排他,因此,严格意义上来说,是有四种分类的锁,分别是:

  1. 共享锁(Shared lock),简称:S锁
  2. 排它锁(Exclusive Locks),简称:X锁
  3. 意向共享锁(Intent Shared lock),简称:IS锁
  4. 意向排他锁(Intent Exclusive Locks),简称:IX锁

接下来,我们就聊聊这些锁都是怎么工作的。

继续深入数据库 了解一下数据库的锁机制

共享锁

共享锁,顾名思义,就是我虽然锁住了这个资源,但是我并不会独占它,我同样允许其他人使用这个资源。

继续深入数据库 了解一下数据库的锁机制

通常情况下,查询就是使用的共享锁。

例如:

事务A先执行了一个查询

select *  from  table; 

事务A还没有执行完,事务B就执行了另一个查询

select *  from  table  where id = 1; 

这个时候,事务B是可以优先于事务A完成他的查询的,并不存在必须要事务A结束,才执行事务B的情况,这就是共享锁的作用。

排它锁

排它锁,又叫独占锁,顾名思义,我锁住了,这东西就是我一个人的,谁也别想看,别想碰。

通常情况下,修改操作就是使用的排它锁。

继续深入数据库 了解一下数据库的锁机制

例如:

事务A先执行了一个修改操作

update  table  set Status = 1; 

事务B还事务A没有完成时,执行了另一个修改操作

update  table  set Status = 0  where id =1; 

这个时候,事务B就只有等着,到事务A执行完成以后,事务B才能够继续,这就是排它锁的作用。

意向锁

共享锁、排它锁按照其作用的粒度,可以锁到行级,也可以锁到页级或表级。不过意向锁只作用于表级,主要是用来标记一个事务对于这张表操作的一个意向。

例如:我有一个事务需要使用表锁,那我就需要知道,这个表是否存在其他的锁,如果有,可能我就需要等待。但是,我如果要排除其他锁,我就需要一个一个记录的遍历,才知道是不是存在行锁。因此,数据库对于行锁就提出另一个机制,就是意向锁,如果你要对这个表进行行锁时,那么先在表上加一个意向锁,方便其他事务查询。

继续深入数据库 了解一下数据库的锁机制

因此,意向锁就有了以下协议:

  • 一个事务获得表t中某行的S锁之前,必须先获得t表上的IS锁或者更强类型的锁。
  • 一个事务获得表t中某行的X锁之前, 必须先获得t表上的IX锁。

现在我们知道了所的类型,接下来我们说说锁的级别。

继续深入数据库 了解一下数据库的锁机制

根据锁的颗粒或者级别不同,我们又把所分为了三个级别:表锁(table-level locking)、页锁(page-level locking)、行锁(row-level locking)。

MyISAM和MEMORY存储引擎采用的是表锁(table-level locking);BDB存储引擎采用的是页锁(page-level locking),但也支持表锁;InnoDB存储引擎既支持行锁(row-level locking),也支持表锁,但默认情况下是采用行锁。

而行锁又包括了三种行锁的算法,分别是:

  1. 记录锁(Record Lock)
  2. 间隙锁(Gap Lock)
  3. 临键锁(Next-Key Lock)

这里有个小知识点:InnoDB的行锁只针对索引项使用,也就是说,只有在通过索引检索数据时,InnoDB才使用行锁,其他时候都是使用的表锁。

记录锁(Record Locks)

记录锁,顾名思义,就是锁住一条记录。这是Read Committed(读提交)事务级别的默认锁级别。

记录锁是作用于索引的,所以,当查询不是作用于索引上时,系统会创建一个隐式的聚集索引,然后作用在索引上。

例如:

select *  from  table  where id = 1 lock  in share mode; 

就是一个共享记录锁,

select *  from  table  for  update  where id = 1 ; 

就是一个排他记录锁。

间隙锁(Gap Lock)

间隙锁,它不会去锁住索引本身,但是会锁住的是一个索引的范围。启用它有一个前置条件,就是数据库隔离级别必须是Repeatable Read(可重复读),这也是InnoDB的默认隔离级别,假设我们将隔离级别降到Read Committed(读提交),间隙锁将会自动失效。

间隙锁的使用,能够有效的防止幻读。

例如:

如果事务A执行了

select *  from  table  where id  between 8  and 15  for  update; 

这是,事务B想在事务A执行期间执行插入一条id是10的记录,就会被阻止。因为这会导致事务A中的多次查询数据不一致。

临键锁(Next-Key Lock)

临键锁就是记录锁+间隙锁的组合方式。这是Repeatable Read(可重复读)隔离级别的默认锁级别。使用临键锁有一个好处,就是,假设我们执行执行一个查询

select *  from  table  where id = 100; 

如果id是唯一索引,那么临键锁就会降级为记录锁,锁住这条记录,而不是去锁住一个范围。

我们讲完了这些锁,那么就不禁要问了,死锁是怎么产生的呢?

这就要说到另一个情况,就是锁的升级。

锁的升级

继续深入数据库 了解一下数据库的锁机制

假设,我们先进行了一个查询,找到了目标数据,然后进行修改,在这个事务中,其实不同的阶段,锁的类型是不同的。

当我们进行查询的时候,我们想数据库先获得了一个共享锁,当我们要对这条数据进行更新的时候,并不是释放共享锁,然后再获取排它锁,而是进行了一个锁的升级操作,直接将共享锁升级成为了排它锁。

而就是因为这个操作,可能导致了死锁。

死锁

继续深入数据库 了解一下数据库的锁机制

假设:事务A中有一个锁升级操作,也就是先执行

select *  from  table  where id =1 

再执行

update  table  set Status = 1  where id =1 

事务B中,同样存在这样的情况,先执行

select *  from  table  where id =1 

再执行

update  table  set  Name = '牛' where id =1 

而执行的顺序恰好是:

  1. 事务A获得了共享锁,执行查询;
  2. 事务B获得了共享锁,执行查询;
  3. 事务A需要升级排它锁,执行修改;
  4. 事务B也需要升级排它锁,不能释放共享锁。

于是,死锁就发生了。当然,还有一种交叉死锁的情况,更为常见,大家可以自己百度看看了。

死锁发生时,数据库并不会直接检查到死锁的存在,只有在锁等待超时的时候被发现,然后杀死其中一个请求。如果并发量高时,死锁就会引起大量的线程挂起,占用大量资源。

怎么预防死锁呢?

最直接的办法就是,别在update前先select一次。

但是,这种情况在所难免,很多时候我们update时,都是需要先select一次的,如果所有地方要求不能select,那代码难度势必就几何级的上升。

还有一种办法就是,加硬件,提高并发能力,这样,出现两次事务同时请求的概率就下降了。不过,这个方式成本太高。

当然,我们还可以直接在查询时,就申请到最终事务需要的锁级别,避免升级锁的出现,也可以预防死锁,例如查询时就直接写

select *  from  table  for  update;  

以上所述就是小编给大家介绍的《继续深入数据库 了解一下数据库的锁机制》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Bandit Algorithms for Website Optimization

Bandit Algorithms for Website Optimization

John Myles White / O'Reilly Media / 2013-1-3 / USD 19.99

This book shows you how to run experiments on your website using A/B testing - and then takes you a huge step further by introducing you to bandit algorithms for website optimization. Author John Myle......一起来看看 《Bandit Algorithms for Website Optimization》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具