码迷,mamicode.com
首页 > 数据库 > 详细

MySQL中的锁

时间:2019-12-17 10:23:31      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:技术   关联   事务隔离级别   版本控制   锁定   记录   开始   语句   安全   

锁的粒度

技术图片

表锁:锁住整个表,加锁和释放速度快,能避免死锁。因为锁住的范围大,并发性低。

页锁:锁住的范围以及性能基于表锁和行锁之间,能支持的主要是BDB(BerkeleyDB)引擎。

行锁:以行为单位进行锁定,粒度最小,并发性高。每次获取锁和释放锁需要做的事情也更多,带来的消耗自然也就更大了。此外,行级锁定也最容易发生死锁。

锁存在升级现象,数据库可能把表中的1000个行锁升级为一个表锁。因为行锁粒度小,占用的资源多,将多个行锁升级为一个表锁,能降低资源的消耗。

共享锁和排他锁

InnoDB的行级锁分为共享锁(Shared Lock、S锁、读锁)和排他锁(Exclusive Lock、X锁、写锁)。

技术图片

意向锁

InnoBD中的意向锁是表级锁,意向锁分为共享意向锁(IS)、排他意向锁(IX)。

技术图片

一致性非锁定读(consistent nonlocking read)

InnoDB存储引擎通过多版本控制(MVVC)来读取当前数据库中的行数据。如果被读取的行正在执行DELETE或UPDATE操作,这时读取操作不会等待行上锁的释放,而会去读取行的一个快照。所以非锁定读机制大大提高了数据库的并发性。

之所以称为非锁定读,因为不需要等待访问的行上的锁的释放。快照数据是指该行的之前版本的数据,该实现是通过undo日志完成的。undo日志本身是用于事务中回滚数据的,因此快照数据是不需要额外开销的。此外,读取快照数据是不需要上锁的,因为没有事务需要对历史的数据进行修改。每行数据可能有多个版本,即可能存在多个快照数据,一般称之为行多版本技术。由此带来的并发控制,称之为多版本并发控制。

一致性非锁定读是InnoDB默认的读取方式,即读取不会占用和等待行上的锁。在事务隔离级别READ COMMITTEDREPEATABLE READ下,InnoDB使用一致性非锁定读。

然而,对于快照数据的定义却不同:

READ COMMITTED事务隔离级别下,一致性非锁定读总是读取被锁定行的最新一份快照数据。这就正如这个隔离级别的名字那样,代表能读取到其他事务中提交的数据,也就是能读取到最新的数据。

REPEATABLE READ事务隔离级别下,则读取事务开始时的行数据版本。可重复读,意味着在事务中的多次相同读取是一致的,也就是不会受其他事务提交数据的影响,所以读取到的数据始终是开始事务时的行快照。

一致性锁定读(Locking Reads)

在以上的一致性非锁定读协议中,读取数据不会对数据行进行加锁,所以其他事务仍可以对被查询的数据行执行更新和删除操作。

在某些情况下,用户可以显式加锁来改变这种默认行为。InnoDB提供了两种类型的锁定读来保证额外的安全性:

SELECT ... LOCK IN SHARE MODE::对读取的行添加S锁,其他事务可以对这些行添加S锁,若添加X锁,则会被阻塞。

SELECT ... FOR UPDATE::会对查询的行及相关联的索引记录加X锁,其他事务请求的S锁或X锁都会被阻塞。

当事务提交或回滚后,通过这两个语句添加的锁都会被释放。当处于默认的自动事务中时,由于语句很快就结束了,并且事务是自动提交的,所以几乎看到以上两个语句所带来的锁影响。

行锁算法

行锁基本的说法是锁住行,但严格来说,锁住的应该是索引记录,因为Innodb中的是以聚簇索引的方式来存储数据的,所以索引记录和行记录的含义是等价的。

Record Lock:锁住索引记录,如果InnoDB存储引擎表在建立的时候没有设置任何一个索引,那么这时InnoDB存储引擎会使用隐式的主键来进行锁定


Gap Lock:间隙锁,锁定一个范围,但不包含记录本身。为了阻止多个事务将记录插入到同一个范围内,设计它的目的是用来解决幻读问题


Next-Key Lock:结合了Gap Lock和Record Lock,锁定一个范围,并且锁定记录本身。

MySQL中的锁

标签:技术   关联   事务隔离级别   版本控制   锁定   记录   开始   语句   安全   

原文地址:https://www.cnblogs.com/hellohello/p/12052871.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!