mysql中Innodb 行锁实现原理

 更新时间:2024年10月21日 10:25:26   作者:程序猿进阶  
InnoDB的行锁是通过索引项加锁实现的,分为使用索引和非索引字段检索的情况,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、Innodb行锁的实现

【1】Innodb的行锁是通过给索引的索引项加锁来实现的

【2】Innodb按照辅助索引进行数据操作时,辅助索引和主键索引都将锁定指定的索引项

【3】通过索引进行数据检索时,Innodb才使用行级锁,否则Innodb将使用表锁

二、场景分析

环境: 创建一张表,ID为主键,Name为普通字段。下面通过实际场景进行说明。

【1】使用主键ID来进行数据检索时,其余行仍然可以操作。

session1session2
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】用非索引的字段来进行数据检索时,此时会升级为表锁,其余列就不能操作。
session1session2
--------
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访问的是不同的记录,但因为使用了相同的索引,所以需要等待锁。
session1session2
--------
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都会使用行锁来对数据加锁。
session1session2
--------
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 行锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:

相关文章

  • mysql 数据表中查找重复记录

    mysql 数据表中查找重复记录

    以下sql语句可以实现查找出一个表中的所有重复的记录
    2009-07-07
  • MySQL使用ReplicationConnection导致连接失效解决

    MySQL使用ReplicationConnection导致连接失效解决

    这篇文章主要为大家介绍了MySQL使用ReplicationConnection导致连接失效问题分析解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • mysql 时间戳的用法

    mysql 时间戳的用法

    这篇文章主要介绍了mysql 时间戳的用法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-08-08
  • MySQL实现分页查询的方法

    MySQL实现分页查询的方法

    这篇文章介绍了MySQL实现分页查询的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • mysql 获取昨天日期、今天日期、明天日期以及前一个小时和后一个小时的时间

    mysql 获取昨天日期、今天日期、明天日期以及前一个小时和后一个小时的时间

    这篇文章主要介绍了mysql 获取昨天日期、今天日期、明天日期以及前一个小时和后一个小时的时间,需要的朋友可以参考下
    2018-01-01
  • MySQL如何开启远程连接权限

    MySQL如何开启远程连接权限

    这篇文章主要介绍了MySQL如何开启远程连接权限问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-09-09
  • Mysql指定日期区间的提取方法

    Mysql指定日期区间的提取方法

    这篇文章主要介绍了Mysql指定日期区间的提取方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-07-07
  • MySQL Server 8.0.13.0 安装教程图文详解

    MySQL Server 8.0.13.0 安装教程图文详解

    本文通过图文并茂的形式给大家介绍了MySQL Server 8.0.13.0 安装教程 ,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • Linux系统下mysql的彻底卸载步骤

    Linux系统下mysql的彻底卸载步骤

    MySQL是一款常用的关系型数据库管理系统,但是在使用过程中,有时候需要卸载MySQL,有些用户在卸载MySQL时会遇到一些问题,这篇文章主要给大家介绍了关于Linux系统下mysql的彻底卸载的相关资料,需要的朋友可以参考下
    2024-07-07
  • mysql手动删除BINLOG的方法

    mysql手动删除BINLOG的方法

    用于删除列于在指定的日志或日期之前的日志索引中的所有二进制日志。这些日志也会从记录在日志索引文件
    2013-03-03

最新评论