Mysql InnoDB存储引擎中的锁

/ 关系型数据库 / 5 条评论 / 1603浏览

数据库软件一方面要最大程度地利用数据库并发访问;另一方面还要确保每个用户能以一致的方式读取和修改数据,为此就有了锁机制。

什么是锁

锁机制用于管理对共享资源的并发访问。

InnoDB存储引擎的SELECT操作默认使用一致性非锁定读。但是在某些情况下,我们需要对读取操作进行加锁。

锁的类型

InnoDB存储引擎支持多粒度锁定,这种锁定允许在行级上的锁和表级锁同时存在。

行级锁

这里有两个概念需要理解。

表级锁

InnoDB存储引擎提供的表级锁也叫意向锁。

SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE

锁的算法

Record Lock

单个行记录上的锁。

Record Lock总是会锁住索引记录。

Gap Lock

间隙锁,锁定一个范围,但不包含记录本身。

Next-Key Lock

锁定一个范围,并且锁定记录本身;也就是行锁和间隙锁的结合。

在Next-Key Lock算法下,InnoDB存储引擎对于行的查询都是采用这种锁定算法,当然,不同的SQL查询语句,可能设置共享的和排他的Next-Key Lock。

例子

当你对一个表执行了 select * from t where a < 6 lock in share mode后, 其他人再对这张表进行 insert into t select 5 这种小于记录6的插入操作时,都会被锁定。此时用到的是Next-Key Lock。

当你对一个表执行了 select * from t where a = 6 lock in share mode后, 其他人再对这张表进行 insert into t select 5 插入记录5(或者记录4)都是可行的。此时用到的是Record Lock。

锁问题

通过锁可以实现事务的隔离性要求,使得事务可以并发的工作。锁提高了并发性,但是却带来了问题。

丢失更新

当出现下面的场景时,就会发生丢失更新:

  1. 事务T1查询一行数据,放入本地内存,并显示给用户User1。
  2. 事务T2也查询本行数据,并将结果显示给用户User2。
  3. User1修改这行记录,更新数据库并提交。
  4. User2修改这行记录,更新数据库并提交。

这时,用户User1修改的数据丢失了。

脏读

脏数据是指未提交的数据。

产生脏读是因为一个事务可以读到另一个事务未提交的数据。

这显然违背了数据库的隔离性。

InnoDB存储引擎默认事务隔离级别为READ REPEATABLE。

不可重复读

不可重复读是指在一个事务内多次读取同一数据。

在这个事务还没有结束时,另外一个事务也访问这一数据。在第一个事务的两次读数据之间,由于第二个事务的修改,第一个事务两次读到的数据可能是不一样的。

阻塞

一个事务的锁需要等待另一个事务中的锁释放它所占的资源。

阻塞并不是一件坏事,阻塞是为了保证事务可以并发并且正常的运行。

死锁

当两个事务互相等待操作同一资源。

InnoDB存储引擎有一个后台的锁监控线程,该线程负责查看可能的死锁问题并告知用户。

InnoDB存储引擎在发生死锁后会马上回滚一个事务,那么另一个事务就会获得资源。

  1. 大佬的博客强啊

  2. 看看行大佬的博客

  3. 大神6的飞起

  4. zailaiyiian hahah

  5. 欧克欧克OK