深入了解Mysql中的锁,聊聊使用场景!
深入了解Mysql中的锁,聊聊使用场景!
Mysql是一个非常流行的关系型数据库管理系统,被广泛使用在各种Web应用中。在使用Mysql时,锁是一个非常重要的概念,对于理解Mysql的并发控制和性能调优都有很大的帮助。本文将围绕常见的锁类型、Mysql引擎介绍、共享锁与排他锁、死锁的发生和解决方式、意向锁和计划锁以及乐观锁和悲观锁展开讨论。
一、常见锁类型
Mysql中常见的锁类型包括:
1.表级锁 - 锁定整张表
2.页级锁 - 锁定一页
3.行级锁 - 锁定一行
4.共享锁 - 又称为S锁,在MyISAM中也叫做读锁
5.排他锁 - 又称为X锁,在MyISAM中也叫做写锁
6.悲观锁 - 抽象性质,其实并不存在
7.乐观锁 - 抽象性质,其实并不存在
其中,行级锁是Mysql的默认锁类型,也是最常用的锁类型,提高了系统并发度和性能,减少了锁冲突。
二、Mysql引擎介绍
Mysql中常用的引擎有很多种类,其中InnoDB和MyISAM引擎最为常用。在Mysql5.5版本之前,默认使用MyISAM引擎,之后默认都使用InnoDB引擎。可以通过以下命令查看数据库引擎:
show variables like '%storage_engine%';
MyISAM引擎操作数据时使用的是表级锁,更新一条记录就需要锁定整个表,导致性能较低,并发性也不高。然而,MyISAM的优点是不会产生死锁问题。相比之下,InnoDB引擎有以下两个最大不同点:一是支持事务,二是采用了行级锁。
三、共享锁与排他锁
在Mysql中,数据库的增删改操作默认会加上排他锁,而查询操作不会加任何锁。常见的锁类型包括共享锁和排他锁,区别如下:
共享锁 - 对某一资源加上共享锁,自身可以读该资源,其他人也可以读该资源。共享锁可同时加多个,但无法修改资源。
排他锁 - 对某一资源加上排他锁,自身可以进行增删改查,其他人无法进行任何操作。
可以通过以下代码实现对表进行共享锁和排他锁的操作:
//共享锁
select * from table_name lock in share mode;
//排他锁
select * from table_name for update;
四、排他锁的实际应用
以下示例展示了两个操作数据库的请求T1和T2,其中T1是查询请求,而T2是更新数据请求。在T1查询较长时间的过程中,T2过来请求更新数据。为了避免冲突,T2必须等待T1完成后,才能继续执行。
T1: select * from table_name lock in share mode; //假设还未返回结果
T2: update table_name set name = 'autofelix';
五、共享锁的实际应用
如果T1和T2都是执行的查询操作,则可以采用共享锁的方式,避免等待。共享锁可以与其他共享锁共存,但是阻止其他用户的修改操作,具体代码如下:
T1: select * from table lock in share mode;
T2: select * from table lock in share mode;
六、死锁的发生
死锁是指两个或多个进程,在运行过程中因争夺资源而造成的相互等待的现象。以下是一种发生死锁的情况:
假设T1和T2都执行了两个资源的操作,其中T1查询并加上了共享锁,T2也加上了共享锁。当T1的查询完成后,准备执行更新操作时,必须将共享锁升级为排他锁。在升级前,必须等待T2的共享锁释放。同样地,T2也在等待T1的共享锁释放。由于互相等待,导致了死锁的发生。
T1: begin; select * from table_name lock in share mode; update table_name set content = 'hello' where id = 10;
T2: begin; select * from table_name lock in share mode; update table_name set content = 'world' where id = 20;
七、另一种发生死锁的情景
当T1和T2都只执行更新语句时,也有可能出现死锁的情况。如果id是主键,由于主键机制,并不需要全表扫描,可以直接更新当前数据,所以不会产生死锁。但如果id是普通字段,那么当T1加上排他锁后,T2为了找到id=20的数据,必须进行全表扫描。当扫描到第10条时,

-
MySQL Workbench怎么建立数据库(附:sql语句创建数据库方法) 2023-07-20 12:22:29
-
MySQL Workbench是什么?(附:如何设置中文教程) 2023-07-20 11:42:31
-
一起聊聊MySQL主从延时的处理方案 2023-05-14 07:00:03
-
mysql怎么将查询结果赋给变量 2023-05-14 07:00:03
-
mysql驱动是什么 2023-05-14 07:00:03
-
qt5.8如何连接mysql 2023-05-14 07:00:03
-
MySQL 语法整理介绍 2023-05-14 07:00:03
-
mysql修改表结构的语句是什么 2023-05-14 07:00:03
-
mysql乐观锁和悲观锁的区别是什么 2023-05-14 07:00:03
-
mysql查询怎么区分大小写 2023-05-14 07:00:02