Innodb 行锁与表锁

2024-02-27 09:38
文章标签 innodb 行锁 表锁

本文主要是介绍Innodb 行锁与表锁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

行锁与表锁

InnoDB默认是行级别的锁,当有明确指定的主键时候,是行级锁。否则是表级别。

#for update的注意点
for update 仅适用于InnoDB,并且必须开启事务,在begin与commit之间才生效。

要测试for update的锁表情况,可以利用MySQL的Command Mode,开启二个视窗来做测试。

1、只根据主键进行查询,并且查询到数据,主键字段产生行锁。

begin;

select * from goods where id = 1 for update;

commit;

2、只根据主键进行查询,没有查询到数据,不产生锁。

begin;

select * from goods where id = 1 for update;

commit;

 

3、根据主键、非主键含索引(name)进行查询,并且查询到数据,主键字段产生行锁,name字段产生行锁。

begin;

select * from goods where id = 1 and name='prod11' for update;

commit;

 

4、根据主键、非主键含索引(name)进行查询,没有查询到数据,不产生锁。

begin;

select * from goods where id = 1 and name='prod12' for update;

commit;

 

5、根据主键、非主键不含索引(name)进行查询,并且查询到数据,如果其他线程按主键字段进行再次查询,则主键字段产生行锁,如果其他线程按非主键不含索引字段进行查询,则非主键不含索引字段产生表锁,如果其他线程按非主键含索引字段进行查询,则非主键含索引字段产生行锁,如果索引值是枚举类型,mysql也会进行表锁,这段话有点拗口,大家仔细理解一下。

 

begin;

select * from goods where id = 1 and name='prod11' for update;

commit;

 

6、根据主键、非主键不含索引(name)进行查询,没有查询到数据,不产生锁。

 

begin;

select * from goods where id = 1 and name='prod12' for update;

commit;

 

7、根据非主键含索引(name)进行查询,并且查询到数据,name字段产生行锁。

 

begin;

select * from goods where name='prod11' for update;

commit;

 

8、根据非主键含索引(name)进行查询,没有查询到数据,不产生锁。

begin;

select * from goods where name='prod11' for update;

commit;

 

9、根据非主键不含索引(stock)进行查询,并且查询到数据,stock字段产生表锁。

begin;

select * from goods where stock='1000' for update;

commit;

 

10、根据非主键不含索引(stock)进行查询,没有查询到数据,stock字段产生表锁。

begin;

select * from goods where stock='2000' for update;

commit;

 

11、只根据主键进行查询,查询条件为不等于,并且查询到数据,主键字段产生表锁。

begin;

select * from goods where id <> 1 for update;

commit;

11.1 

begin;

select * from goods where id < 5 and id <> 1 for update;

commit;

这条查询仅仅会返回2 ~ 4之间的行,但是实际上获取了 1 ~ 4之间的行的排他锁。InnoDB会锁住第1行  ---- 底层存储引擎的操作是“从索引的开头开始获取满足条件id < 5的记录” ,服务器并没有告诉InnoDB可以过滤第1行的where条件, 需要MySQL服务器将存储引擎返回行以后再应用where过滤条件(Extra  Using where)。

 

12、只根据主键进行查询,查询条件为不等于,没有查询到数据,主键字段产生表锁。

begin;

select * from goods where id <> 1 for update;

commit;

 

13、只根据主键进行查询,查询条件为 like,并且查询到数据,主键字段产生表锁。

begin;

select * from goods where id like '1' for update;

commit;

 

14、只根据主键进行查询,查询条件为 like,没有查询到数据,主键字段产生表锁。

 

begin;

select * from goods where id like '1' for update;

commit;

总结

1、InnoDB行锁是通过给索引上的索引项加锁来实现的,只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。

2、由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。

3、当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。

4、即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL的执行计划,以确认是否真正使用了索引。

5、检索值的数据类型与索引字段不同,虽然MySQL能够进行数据类型转换,但却不会使用索引,从而导致InnoDB使用表锁。通过用explain检查两条SQL的执行计划,我们可以清楚地看到了这一点。(此条本地验证后发现 数据库类型为varchar时 查询用 数字类型时用不了索引 。但数据库类型为int、  datetime时 查询类型为字符串 也可以走索引)

这篇关于Innodb 行锁与表锁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/751978

相关文章

InnoDB的多版本一致性读的实现

InnoDB是支持MVCC多版本一致性读的,因此和其他实现了MVCC的系统如Oracle,PostgreSQL一样,读不会阻塞写,写也不会阻塞读。虽然同样是MVCC,各家的实现是不太一样的。Oracle通过在block头部的事务列表,和记录中的锁标志位,加上回滚段,个人认为实现上是最优雅的方式。 而PostgreSQL则更是将多个版本的数据都放在表中,而没有单独的回滚段,导致的一个结果是回滚非

MySQL技术内幕_innodb存储引擎

MySQL技术内幕_innodb存储引擎 INNODB innodb中如果表没有主键 表是否由 非空唯一键,有则该字段为主键没有,则自动创建一个6字节大小的指针 innodb存储引擎的所有数据都存储在表空间中,表空间由段,区,页(块)组成。 如果启用了 innodb_file_per_table, 则每张表内的数据可以单独放在一个表空间中即使启用了上面参数,共享表空间也会因为 系统事务信息

Mysql中的隐式COMMIT以及Savepoints的作用以及MySQL的Innodb分空间存储、设计优化、索引等几个小知识点整理

一、Mysql中的隐式COMMIT以及Savepoints的作用     Mysql默认是自动提交的,如果要开启使用事务,首先要关闭自动提交后START TRANSACTION 或者 BEGIN 来开始一个事务,使用ROLLBACK/COMMIT来结束一个事务。但即使如此,也并不是所有的操作都能被ROLLBACK,以下语句在执行后会导致回滚失效,比如DDL语句创建一个数据库,而且不止此,这样的语

MySQL Innodb 插入调优

1)提高数据库插入性能中心思想:尽量将数据一次性写入到Data File和减少数据库的checkpoint 操作。这次修改了下面四个配置项:  1)将 innodb_flush_log_at_trx_commit 配置设定为0;按过往经验设定为0,插入速度会有很大提高。 0: Write the log buffer to the log file and flush the

MySql系列之Innodb存储引擎

插件化存储引擎是MySQL特点,用户可以根据自己的需求使用不同的存储引擎,甚至通过抽象的API接口实现自己的存储引擎。innodb存储引擎支持行级锁以及事务特性,也是多种场合使用较多的存储引擎,本文将介绍innodb存储引擎。 存储引擎简介 mysql系统来说,存储引擎是真正实现数据的存储与读取操作的对象,数据库实例通过抽象API接口与存储引擎交互,存储引擎自定义实现数据的物理、逻辑组织形式以

mysql5.6InnoDB通过frm与ibd对数据进行恢复

1. 安装MySQL Utilities 下载地址:https://dev.mysql.com/downloads/utilities/ 下载完后直接安装即可 如果运行时需要python就下载 https://dev.mysql.com/downloads/connector/python/ 本机还需要安装与需要恢复数据的一样版本的Mysql 2. 使用mysqlfrm命令读取frm

MySQL基础学习:为什么推荐使用InnoDB而不是MyISM

这里写自定义目录标题 一、事务支持二、锁机制三、外键支持四、性能和优化五、崩溃恢复能力六、其他特性 一、事务支持 InnoDB:支持事务处理,通过ACID(原子性、一致性、隔离性、持久性)事务模型保证数据的完整性和一致性。这对于需要保证数据一致性和可靠性的应用场景至关重要。MyISAM:不支持事务处理,这在进行大量数据修改时可能导致数据不一致的风险。 二、锁机制 InnoDB

mysql innodb分表实战

目的:为了了解mysql单表分区方法,特此作为学习笔记记录一下。 一。准备表,创建一个学生表,包含主键sid和名称sname字段 create table students( sid int(5) primary key, sname varchar(24) ); 二。准备数据 insert into students(sid,sname) values(10003,'tom

Mysql剖析(四)----Mysql的行锁、表锁、间隙锁详解

目录 一丶Mysql的锁分类 二丶乐观锁和悲观锁 三丶共享锁和排它锁 四丶表锁页锁和行锁 五丶Mysql锁超时 简介:编程中的锁是一种同步机制,用于控制对共享资源的访问,确保同一时间只有一个线程可以访问共享资源,从而避免竞态条件和其他并发问题,保证线程安全和正确的数据访问。锁的概念来源于日常生活,其中锁和钥匙用于控制对某个空间的访问,确保安全隐私。在编程中,锁用于控制对共享资源

带你从根本理解mysql innodb的各种锁

锁的相关概念: 锁:数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。而锁就是并发控制的一个重要的手段。 表锁:对某个表进行加锁。能够保证不会出现死锁,但是发生锁冲突几率高,并发性能差。 排他锁(X):排他锁也叫“写锁”,获得某个表的排他锁的事务便拥有了对这个