【MySQL】mysql中的锁机制
一、分类
MySQL的锁机制不同的存储引擎支持不同的锁机制,分为表级锁、行级锁、页面锁。MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁;InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
二、表级锁
MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。
对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;对 MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作。
MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作 (UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用LOCK TABLE命令给MyISAM表显式加锁。
三、行级锁
InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。
行级锁也支持读锁和写锁两类。
1、如何加锁?
mysql InnoDB引擎默认的修改数据语句:update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select …for update语句,加共享锁可以使用select … lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。
2、实现原理
InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,并请求共享或排他锁时,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
四、锁的算法
record lock:单个记录的锁。
gap lock:间隙锁,锁定一个范围,不包括记录本身
next-key lock:gap lock+record lock
默认隔离级别(可重复读)下,默认加的是next-key lock(为了解决幻读问题),当索引中含有唯一属性时(唯一索引,主键索引),会降级为record lock。
在读已提交隔离级别下,加的是record lock
1、例1
现在表z,有a,b两列,a是主键,全表只有一个主键索引。现在记录如下:(1,1)(3,1)(5,3)(7,6)(10,8)
select * from z where b=3 for update
因为b没有索引,所以走得是全表扫描。有因为加锁是通过对索引加锁实现,因为没有走索引,所有会锁整个表,也就是表锁
2、例2
现在表z,有a,b两列,a是主键索引,b建立辅助索引。现在记录如下:(1,1)(3,1)(5,3)(7,6)(10,8)
select * from z where a=3 for update
主键索引加的锁是record lock,对记录(3,1)加锁
select * from z where b=3 for update
因为锁是通过对索引加锁实现的。所以这里需要对主键索引和辅助索引加锁,主键索引加的锁会由next-key锁退化成是record lock,辅助索引加的锁是next-key lock,锁定范围是(1,3)、3、(3,6)
五、select的几种类型
1、快照读
读取的是快照版本,也就是历史版本。普通的SELECT就是快照读
2、当前读
读取的是最新版本。
UPDATE、DELETE、INSERT、SELECT ... LOCK IN SHARE MODE、SELECT ... FOR UPDATE是当前读。
默认的可重复读隔离级别,使用的是快照读
读已提交使用的是当前读
3、一致性非锁定读
实现原理是通过MVCC机制实现,如果读取的行正处于update或delete中,读操作不会去等待行上X锁的释放,而是去读取行的快照数据。
MVCC,多版本并发控制技术。在 InnoDB 中,在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号。通过版本号和行锁,从而提高数据库系统并发性能。
一致性非锁定读可以极大的提高并发性能
不同的事务隔离级别,读取的快照版本是有差别的
读已提交隔离级别,总是读取最新的快照版本。可能会产生幻读
可重复读隔离级别,总是读取事务开始后第一次读取的快照版本。可以避免幻读的产生
4、一致性锁定读
默认配置下,采用可重复读的隔离级别,读取数据采取的是一致性非锁定读。
但是某些场景下需要对读取操作加锁来保证严格的数据一致性,这时候可以显式的对读取的记录进行加锁:
select *** for update(对读取记录加X锁)
给索引记录加锁,这种情况下跟UPDATE的加锁情况是一样的
select *** lock in share model(对读取记录加S锁)
给记录假设共享锁,这样一来的话,其它事务只能读不能修改,直到当前事务提交
作者:leon66666
出处:http://www.cnblogs.com/wangzhongqiu/
![]()
如果你觉得文章不错,文末的赞 👍 又回来啦,记得给我「点赞」和「在看」哦~
本文分享自微信公众号 - JAVA高级架构(gaojijiagou)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
玩转Redis-生产环境如何导入、导出及删除大量数据
《玩转Redis》系列文章主要讲述Redis的基础及中高级应用。本文是《玩转Redis》系列第【13】篇,最新系列文章请前往公众号“zxiaofan”(点我点我)查看,或百度搜索“玩转Redis zxiaofan”即可。 本文关键字:玩转Redis、Redis数据导入、Redis大量插入、Redis数据导出、Redis导出指定通配符、Redis数据删除、Redis批量删除、Redis删除指定前缀key、Redis删除指定通配符key; 往期精选:《玩转Redis-删除了两百万key,为什么内存依旧未释放?》 大纲 Redis生产环境安全高效导入大量数据 使用shell脚本构造测试数据 Redis非集群模式导入大量数据 Redis集群模式导入大量数据 Redis生产环境安全高效导出大量数据 Redis导入导出所有数据 Redis导出指定前缀(指定通配符)数据 Redis生产环境安全高效删除数据 Redis删除已知的指定key Redis删除指定前缀(指定通配符)数据 实用小技巧 Redis统计指定通配符key的数量 免输密码连接Redis脚本 思考题:Linux可以设置脚本可执行但不...
- 下一篇
数学上的闭包概念及与编程的关系
首先, 需要强调一点, 这里谈论的 闭包(closure) 概念是指数学上的, 不是我们编程界一般谈论的那个闭包. 在编程实践中, 闭包另有定义, 是一种为表示带有自由变量的过程而用的实现技术. 但另一方面, 这个数学上的闭包概念在编程实践中依然是有体现, 虽然不同于编程界一般谈论的那个闭包, 后面会举一些例子加以说明. 闭包到底是什么? 闭包在数学上是一个比较抽象的概念, 来自于抽象代数, 因此这里不打算直接给出它的定义, 否则大家看了估计还是一头雾水, 为便于理解, 还是先从具体的例子出发, 最后才给出它的定义. 以加法在自然数集合中为例 我们先考察一个很简单的例子, 就是加法在自然数集合中的操作及其结果. 首先, 自然数集这个很好理解, 就是0, 1, 2, 3..., 这些整数的集合, 当然需要注意的一点是它是一个无穷的集合. 然后是加法这个操作, 我们也很熟悉, 它需要两个操作数, 从刚才的自然数集合中任意取出两个数, 然后执行加法操作: 比如, 1 + 2, 3 + 5, 6 + 4 等等 然后这些加法操作会有一个结果, 比如 1 + 2 = 3, 3 + 5 = 8, 6...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Hadoop3单机部署,实现最简伪集群
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Windows10,CentOS7,CentOS8安装Nodejs环境
- MySQL8.0.19开启GTID主从同步CentOS8