MySQL进阶
01、MySQL进阶:剖析MySQL索引底层数据结构
02、MySQL进阶:MySQL不同存储引擎下索引的实现
03、MySQL进阶:Explain深度剖析
04、MySQL进阶:践行索引优化
05、MySQL进阶:锁等待及死锁初探
06、MySQL进阶:无索引行锁升级为表锁
07、MySQL进阶:共享锁和排它锁初探
08、MySQL进阶:索引优化案例实操
09、MySQL进阶:索引下推IndexConditionPushdown初探
10、MySQL进阶:使用trace工具来窥探MySQL是如何选择执行计划的
11、MySQL进阶:orderby和groupby优化初探
12、MySQL进阶:分页查询优化的两个案例解析
13、MySQL进阶:Join关联查询优化
14、MySQL进阶:In和Exists的优化案例讲解
15、MySQL进阶:存储引擎初探
16、MySQL进阶:体系结构初探
17、MySQL进阶:解读MySQL事务与锁机制
18、MySQL进阶:多版本控制MVCC机制初探
19、MySQL进阶:并发事务问题及解决方案
20、MySQL进阶:锁机制初探
21、MySQL进阶:高效的设计MySQL库表
22、MySQL进阶:库表设计之IP和TIMESTAMP的处理
23、MySQL进阶:orderby出现usingfilesort根因分析及优化
24、MySQL进阶:canal实现mysql数据同步到redis|实现自定义canal客户端
本文档使用 MrDoc 发布
-
+
首页
07、MySQL进阶:共享锁和排它锁初探
 ### **官方文档** 锁定某一行可以用lock in share mode(共享锁) 和for update(排它锁) 官方文档: [https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html "https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html")  大体过一下 如果你在查询数据,然后在同一个事务里插入或者修改相关的数据,常规的 select 语句不会提供足够的保护。其他的事务可以修改或者删除你正在查询的行。 InnoDB 支持两种可以提供安全机制的读取锁: - SELECT … LOCK IN SHARE MODE 在读取的行上设置一个共享锁,其他的session可以读这些行,但在你的事务提交之前不可以修改它们。如果这些行里有被其他的还没有提交的事务修改,你的查询会等到那个事务结束之后使用最新的值 - 索引搜索遇到的记录,SELECT … FOR UPDATE 会锁住行及任何关联的索引条目,和你对那些行执行 update 语句相同。其他的事务会被阻塞在对这些行执行 update 操作,获取共享锁,或从某些事务隔离级别读取数据等操作。 一致性读(Consistent Nonlocking Reads)会忽略在读取视图上的记录的任何锁。(旧版本的记录不能被锁定;它们通过应用撤销日志在记录的内存副本上时被重建。) **所有被共享锁和排他锁查询所设置的锁都会在事务提交或者回滚之后被释放。** **注:** - 使用 SELECT FOR UPDATE 为 update 操作锁定行,只适用于 autocommit 被禁用(当使用 START TRANSACTION 开始事务或者设置 autocommit 为0时)。 - 如果 autocommit 已启用,符合规范的行不会被锁定。 ### **事务隔离级别** **默认的RR** ```python mysql> show variables like '%iso%'; +-----------------------+-----------------+ | Variable_name | Value | +-----------------------+-----------------+ | transaction_isolation | REPEATABLE-READ | +-----------------------+-----------------+ 1 row in set mysql> ``` ------------ ### **共享锁 VS 排他锁的区别** - SELECT … LOCK IN SHARE MODE :共享锁(S锁, share locks)。其他事务可以读取数据,但不能对该数据进行修改,直到所有的共享锁被释放。 **如果事务对某行数据加上共享锁之后,可进行读写操作;其他事务可以对该数据加共享锁,但不能加排他锁,且只能读数据,不能修改数据。** - SELECT … FOR UPDATE:排他锁(X锁, exclusive locks)。**如果事务对数据加上排他锁之后,则其他事务不能对该数据加任何的锁。获取排他锁的事务既能读取数据,也能修改数据。** 普通 select 语句默认不加锁,而CUD操作默认加排他锁。 ------------ ### **SELECT … FOR UPDATE 排它锁 演示** 对所在行加上了一把排它锁 x锁 【实验步骤】 | session1 | session2 | | --- | --- | | begin 模拟开启事务 | | | select * from country where countrycode = ‘CN’ for update ; --读取成功,但未提交事务 | | | | begin 模拟开启事务 | | | select * from country where countrycode = ‘CN’ for update ; ---- 可以读取成功 | | | update country set countryname=‘新中国’ where countrycode = ‘CN’; ---- 一直被阻塞,如果会话一一直没提交,session2 直到超时,抛出如下异常 1205 - Lock wait timeout exceeded; try restarting transaction | 【结论】 通过上述实验 ,我们可以推断出其他session只能读该行数据,修改则会被阻塞,直到锁定行的session提交事务 ------------ ### **SELECT … LOCK IN SHARE MODE 共享锁 演示** | session1 | session2 | | --- | --- | | begin 模拟开启事务 | | | select * from country where countrycode = ‘CN’ lock in share mode ; --读取成功,但未提交事务 | | | | begin 模拟开启事务 | | | select * from country where countrycode = ‘CN’ lock in share mode ; ---- 可以加共享锁 | | | select * from country where countrycode = ‘CN’ for update ; ---- 不能加排它锁 一直被阻塞 | | | update country set countryname=‘China’ where countrycode = ‘CN’ ; — 修改该行数据也被阻塞,如果事务一还没提交,一直等到超时 1205 - Lock wait timeout exceeded; try restarting transaction |
李智
2025年3月17日 13:31
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码