文章目录

  • 前言
  • 一、锁分类
  • 从对数据操作的粒度分 :
  • 1) 表锁:操作时,会锁定整个表。
  • 2) 行锁:操作时,会锁定当前操作行。
  • 从对数据操作的类型分:
  • 1) 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响。
  • 2) 写锁(排它锁):当前操作没有完成之前,它会阻断其他写锁和读锁。
  • 二、Mysql 锁
  • 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。下表中罗列出了各存储引擎对锁的支持情况:
  • MySQL这3种锁的特性可大致归纳如下 :
  • 2.InnoDB 行锁
  • 行锁介绍
  • InnoDB 的行锁模式
  • 共享锁
  • 排他锁
  • 三种行锁
  • Record Lock:
  • Gap Lock :
  • Next-Key Lock :
  • 总结
  • 优化建议:



前言

锁是计算机协调多个进程或线程并发访问某一资源的机制(避免争抢)。
在数据库中,除传统的计算资源(如 CPU、RAM、I/O 等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。


一、锁分类

从对数据操作的粒度分 :

1) 表锁:操作时,会锁定整个表。

2) 行锁:操作时,会锁定当前操作行。

从对数据操作的类型分:

1) 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响。

2) 写锁(排它锁):当前操作没有完成之前,它会阻断其他写锁和读锁。

二、Mysql 锁

相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。下表中罗列出了各存储引擎对锁的支持情况:

存储引擎

表级锁

行级锁

MyISAM

支持

不支持

InnoDB

支持

支持

MEMORY

支持

不支持

BDB

支持

不支持

MySQL这3种锁的特性可大致归纳如下 :

锁类型

特点

表级锁

偏向MyISAM 存储引擎,开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

行级锁

偏向InnoDB 存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

页面锁

开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

从上述特点可见,很难笼统地说哪种锁更好,只能就具体应用的特点来说哪种锁更合适!仅从锁的角度来说:表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web 应用;而行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并查询的应用,如一些在线事务处理(OLTP)系统。

2.InnoDB 行锁

行锁介绍

行锁特点 :偏向InnoDB 存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
InnoDB 与 MyISAM 的最大不同有两点:一是支持事务;二是 采用了行级锁。

InnoDB 的行锁模式

InnoDB 实现了以下两种类型的行锁:

共享锁

(S):又称为读锁,简称S锁,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。

排他锁

(X):又称为写锁,简称X锁,排他锁就是不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。

对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);
对于普通SELECT语句,InnoDB不会加任何锁;
可以通过以下语句显示给记录集加共享锁或排他锁 。
共享锁(S):SELECT * FROM table_name WHERE … LOCK IN SHARE MODE
排他锁(X) :SELECT * FROM table_name WHERE … FOR UPDATE

三种行锁
Record Lock:

单个行记录上的锁,Record Lock总是会锁住索引记录,如果InnoDB存储引擎在建立标的时候没有设置索引,这个时候会用隐式的主键来锁定.

Gap Lock :

间隙锁,锁定一个范围,但不包含本身
Gap Lock锁主要是用来锁住间隙的.也就是为了阻止多个事务将记录插入到同一范围内,这会导致幻读问题的产生.

Next-Key Lock :

Gap Lock+ Recork Lock,锁定一个范围,并且锁定记录本身
Next-Key Lock是结合了Gap Lock 和Record Lock的一种锁定算法.这种算法锁定的并不是单个值,而是一个范围.这个锁的出现也是为了防止幻读的出现.

总结

InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面带来了性能损耗可能比表锁会更高一些,但是在整体并发处理能力方面要远远由于MyISAM的表锁的。当系统并发量较高的时候,InnoDB的整体性能和MyISAM相比就会有比较明显的优势。
但是,InnoDB的行级锁同样也有其脆弱的一面,当我们使用不当的时候,可能会让InnoDB的整体性能表现不仅不能比MyISAM高,甚至可能会更差。

优化建议:

  • 尽可能让所有数据检索都能通过索引来完成,避免无索引行锁升级为表锁。
  • 合理设计索引,尽量缩小锁的范围
  • 尽可能减少索引条件,及索引范围,避免间隙锁
  • 尽量控制事务大小,减少锁定资源量和时间长度
  • 尽可使用低级别事务隔离(但是需要业务层面满足需求)