目录
- 一、Innodb行锁的实现
- 二、场景分析
- 三、特殊场景
一、Innodb行锁的实现
【1】Innodb的行锁是通过给索引的索引项加锁来实现的
【2】Innodb
按照辅助索引进行数据操作时,辅助索引和主键索引都将锁定指定的索引项
【3】通过索引进行数据检索时,Innodb
才使用行级锁,否则Innodb
将使用表锁
二、场景分析
环境: 创建一张表,ID为主键,Name为普通字段。下面通过实际场景进行说明。
【1】使用主键ID来进行数据检索时,其余行仍然可以操作。
session1 | session2 |
---|---|
mysql>set autocommit=0; Query OK,0 rows affected(0.00sec) | mysql>set autocommit=0; Query OK,0 rows affected(0.00sec) |
mysql> select * from test_lock wehre id = 1 for update; ±-----±-----+ | id | name | | 1 | hua zi | 1 row in set(0.00sec) | |
mysql> select * from test_lock wehre id = 2 for update; ±-----±-----+ | id | name | | 2 | guo zi | 1 row in set(0.00sec) | |
【2】用非索引的字段来进行数据检索时,此时会升级为表锁,其余列就不能操作。 | |
session1 | session2 |
---- | ---- |
mysql>set autocommit=0; Query OK,0 rows affected(0.00sec) | mysql>set autocommit=0; Query OK,0 rows affected(0.00sec) |
mysql> select * from test_lock wehre name = ‘hua zi’ for update; ±-----±-----+ | id | name | | 1 | hua zi | 1 row in set(0.00sec) | |
mysql> select * from test_lock wehre name = ‘guo zi’ for update; 等待 | |
【3】由于MySQL 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。虽然 session_2和session_1访问的是不同的记录,但因为使用了相同的索引,所以需要等待锁。 | |
session1 | session2 |
---- | ---- |
mysql>set autocommit=0; Query OK,0 rows affected(0.00sec) | mysql>set autocommit=0; Query OK,0 rows affected(0.00sec) |
mysql> select * from test_lock wehre id = 1 and name = ‘hua zi’ for update; ±-----±-----+ | id | name | | 1 | hua zi | 1 row in set(0.00sec) | |
mysql> select * from test_lock wehre id = 1 and name = ‘guo zi’ for update; 等待 | |
【4】当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB 都会使用行锁来对数据加锁。 | |
session1 | session2 |
---- | ---- |
mysql>set autocommit=0; Query OK,0 rows affected(0.00sec) | mysql>set autocommit=0; Query OK,0 rows affected(0.00sec) |
mysql> select * from test_lock wehre id = 1 for update; ±-----±-----+ | id | name | | 1 | hua zi | 1 row in set(0.00sec) | |
mysql> select * from test_lock wehre name = ‘guo zi’ for update; ±-----±-----+ | id | name | | 2 | guo zi | 1 row in set(0.00sec) | |
mysql> select * from test_lock wehre name = ‘hua zi’ for update; 等待 |
三、特殊场景
即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL
通过判断不同执行计划的代价来决定的,如果MySQL
认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB
将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL
的执行计划,以确认是否真正使用了索引。
在下面的例子中,检索值的数据类型与索引字段不同,虽然MySQL
能够进行数据类型转换,但却不会使用索引,从而导致InnoDB
使用表锁。通过用explain
检查两条SQL
的执行计划,我们可以清楚地看到了这一点。
mysql> alter table test_lock add index name(name);
Query OK, 4 rows affected (8.06 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> explain select * from test_lock where name = 1 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_lock
type: ALL
possible_keys: name
key: NULL
key_len: NULL
ref: NULL
rows: 4
Extra: Using where
1 row in set (0.00 sec)
mysql> explain select * from test_lock where name = '1' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_lock
type: ref
possible_keys: name
key: name
key_len: 23
ref: const
rows: 1
Extra: Using where
1 row in set (0.00 sec)
到此这篇关于mysql中Innodb 行锁实现原理的文章就介绍到这了,更多相关mysql Innodb 行锁内容请搜索编程客栈(www.lsjlt.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网(www.lsjlt.com)!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1148
183.71 KB下载数642
644.84 KB下载数2756
相关文章
发现更多好内容- 如何在 Java 中实现对正方形的缩放操作?(如何在Java中对正方形进行缩放操作)
- 如何正确使用 Java 的 join 方法?(java join方法怎么使用)
- Java 中 DecimalFormat 在哪些场景下使用较为合适?(Java DecimalFormat在哪里使用合适)
- 如何确保Redis客户端的安全性:实用技巧与最佳实践
- 在 JavaScript 中如何使用 parentNode?(javascript中的parentNode怎么用)
- 如何高效编码 Java Supplier 接口?(java supplier接口的高效编码技巧)
- 如何进行 Java NoSQL 查询优化?(java nosql查询优化怎样进行)
- Java 中 `equals()` 的核心究竟是什么?(java eques的核心是什么)
- Java代理模式的优缺点分别有哪些?(Java代理模式有哪些优缺点)
- 2024下半年北京软考成绩复查时间及流程