MySQL 系统学习 第四阶段:MySQL 高级 第五节:锁机制(Lock)
2026/7/14 5:17:49 网站建设 项目流程

上一节我们学习了事务。

事务解决:

一组操作要么全部成功,要么全部失败。

但是还有一个问题:

多个事务同时操作同一份数据怎么办?

例如:

商品库存:

商品A 库存:1

两个用户同时购买:

用户A 下单 用户B 下单

两个事务同时读取:

库存=1

然后:

库存 - 1

结果:

库存=-1

这就是并发问题。


一、为什么需要锁?

锁的本质:

控制多个事务对共享资源的访问顺序,保证数据一致性。

简单理解:

没有锁:

事务A | | 修改数据 | 事务B | | 同时修改数据

可能产生冲突。


有锁:

事务A | | 获取锁 | | 修改数据 | | 释放锁 事务B | | 等待

保证数据安全。


二、MySQL 中锁的分类

MySQL 锁很多,我们先掌握核心分类。

按照粒度:

锁 │ ├── 表级锁 │ └── 行级锁

按照功能:

锁 │ ├── 共享锁(S锁) │ └── 排他锁(X锁)

按照思想:

锁 │ ├── 悲观锁 │ └── 乐观锁

三、表锁(Table Lock)

什么是表锁?

锁住整张表。

例如:

user表 +----+ | | | 🔒 | | | +----+

其他事务:

不能修改。


示例

加表锁:

LOCK TABLE user WRITE;

释放:

UNLOCK TABLES;

四、表锁特点

优点:

简单。

加锁成本低。


缺点:

并发能力差。

例如:

用户表:

100万用户。

修改其中一个用户:

UPDATE user SET name='Tom' WHERE id=1;

如果使用表锁:

整个 user 表被锁。

其他用户:

不能修改。


所以:

表锁适合低并发场景。


五、行锁(Row Lock)⭐⭐⭐⭐⭐

什么是行锁?

只锁定某一条数据。

例如:

修改:

UPDATE user SET name='Tom' WHERE id=1;

锁:

id=1 🔒

其他:

id=2 id=3

仍然可以操作。


六、行锁的优势

假设:

用户表:

100万数据。

两个事务:

事务A:

UPDATE user SET name='Tom' WHERE id=1;

事务B:

UPDATE user SET name='Jack' WHERE id=2;

因为:

锁不同数据。

可以同时执行。


所以:

行锁大幅提高并发能力。


七、为什么 InnoDB 支持行锁?

MySQL 存储引擎:

MyISAM

只支持:

表锁

InnoDB

支持:

表锁 + 行锁

所以:

企业项目通常使用:

InnoDB

八、共享锁(Shared Lock)

简称:

S锁

也叫:

读锁。


作用:

多个事务可以同时读取,但不能修改。


例如:

事务A:

SELECT * FROM user WHERE id=1 FOR SHARE;

加共享锁。


事务B:

可以:

SELECT


但是:

UPDATE user SET name='Tom' WHERE id=1;

等待锁释放。


九、排他锁(Exclusive Lock)

简称:

X锁

也叫:

写锁。


作用:

一个事务获得后,其他事务不能读写。


例如:

SELECT * FROM user WHERE id=1 FOR UPDATE;

加排他锁。


事务A:

修改:

UPDATE user SET name='Tom' WHERE id=1;

可以。


事务B:

修改同一条:

UPDATE user SET name='Jack' WHERE id=1;

等待。


十、共享锁和排他锁区别

共享锁 S排他锁 X
作用读取修改
别人能读❌(部分情况)
别人能写
使用场景保证读取一致保证修改安全

十一、悲观锁(Pessimistic Lock)⭐⭐⭐⭐⭐

思想:

数据很可能会被别人修改,所以提前加锁。


例如:

库存扣减:

库存:

100

用户购买:

先锁:

SELECT stock FROM product WHERE id=1 FOR UPDATE;

然后:

UPDATE product SET stock=stock-1 WHERE id=1;

特点:

安全。

但是:

并发低。


十二、乐观锁(Optimistic Lock)⭐⭐⭐⭐⭐

思想:

默认认为不会冲突,提交时检查有没有被修改。

常见方式:

增加版本号。


表:

product id stock version

数据:

id=1 stock=100 version=1

事务A:

读取:

stock=100 version=1

事务B:

修改:

stock=99 version=2

事务A提交:

UPDATE product SET stock=99, version=2 WHERE id=1 AND version=1;

发现:

影响行数:

0

说明:

数据已经被修改。

提交失败。


十三、悲观锁 vs 乐观锁

悲观锁乐观锁
思想提前锁住提交检查
方式数据库锁版本号
并发能力
安全性需要处理冲突
适合冲突频繁冲突较少

十四、企业实际案例:库存扣减

假设:

库存:

stock=1

两个请求:


错误方式

查询:

SELECT stock FROM product WHERE id=1;

返回:

1

两个请求都看到:

1

然后:

UPDATE product SET stock=0

问题:

超卖。


方案1:悲观锁

BEGIN; SELECT stock FROM product WHERE id=1 FOR UPDATE; UPDATE product SET stock=stock-1 WHERE id=1; COMMIT;

方案2:乐观锁

增加:

version

执行:

UPDATE product SET stock=stock-1, version=version+1 WHERE id=1 AND version=10;

成功:

影响行数=1

失败:

重新尝试。


十五、锁等待和死锁

锁等待

事务A:

锁住:

用户1

事务B:

想修改:

用户1

结果:

B等待。


死锁(Dead Lock)

例如:

事务A:

锁:

A数据

等待:

B数据

事务B:

锁:

B数据

等待:

A数据

形成:

A 等 B B 等 A

数据库检测后:

回滚其中一个事务。


十六、本节总结

概念说明
控制并发访问
表锁锁整张表
行锁锁具体数据行
共享锁读锁
排他锁写锁
悲观锁先加锁再操作
乐观锁提交时检查
死锁多个事务互相等待

🎯 本节核心一句话:

锁是数据库保证并发安全的机制,InnoDB 通过行锁让多个事务能够安全并发执行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询