MySQL悲观锁和乐观锁

MySQL悲观锁和乐观锁

在数据库中,锁是用来管理并发控制的一种机制,确保数据的一致性和完整性。MySQL中的悲观锁和乐观锁是两种不同的并发控制策略,它们在处理并发事务时采用不同的方法。

悲观锁(Pessimistic Locking)

悲观锁假设会发生冲突,因此它会在事务开始时锁定数据,阻止其他事务修改这些数据,直到当前事务完成。

  • 适用场景:适用于写操作多的场景,因为写操作之间是互斥的。
  • 实现方式 :通常通过SELECT ... FOR UPDATE语句实现。
乐观锁(Optimistic Locking)

乐观锁假设冲突发生的概率较小,因此它不会在事务开始时锁定数据。相反,它会在数据提交时检查在事务执行期间数据是否被其他事务修改过。

  • 适用场景:适用于读操作多的场景,因为读操作之间不是互斥的。
  • 实现方式:通常通过版本号(version)或时间戳(timestamp)实现。

案例演示

悲观锁案例

假设我们有一个orders表,其中包含订单数据,我们希望在更新订单状态时使用悲观锁。

sql 复制代码
-- 创建表
CREATE TABLE orders (
    id INT PRIMARY KEY,
    product_name VARCHAR(100),
    order_status VARCHAR(10),
    order_amount INT
);

-- 插入测试数据
INSERT INTO orders (id, product_name, order_status, order_amount) VALUES (1, 'Laptop', 'PENDING', 1000);

使用悲观锁更新订单状态:

sql 复制代码
-- 开启事务
START TRANSACTION;

-- 锁定特定行并更新
SELECT * FROM orders WHERE id = 1 FOR UPDATE;

-- 更新订单状态
UPDATE orders SET order_status = 'SHIPPED' WHERE id = 1;

-- 提交事务
COMMIT;

在这个案例中,SELECT ... FOR UPDATE语句锁定了id = 1的行,直到事务提交,其他事务都不能修改这行数据。

乐观锁案例

假设我们有一个products表,其中包含产品信息和版本号。

sql 复制代码
-- 创建表
CREATE TABLE products (
    id INT PRIMARY KEY,
    product_name VARCHAR(100),
    version INT DEFAULT 1
);

-- 插入测试数据
INSERT INTO products (id, product_name) VALUES (1, 'Smartphone');

使用乐观锁更新产品名称:

sql 复制代码
-- 读取产品信息和版本号
SELECT id, product_name, version FROM products WHERE id = 1;

-- 假设读取到的版本号是1,现在更新产品名称和版本号
UPDATE products SET product_name = 'Updated Smartphone', version = version + 1 WHERE id = 1 AND version = 1;

-- 如果没有行被更新,说明在读取和更新之间有其他事务更新了数据

在这个案例中,我们通过版本号来实现乐观锁。当我们尝试更新产品名称时,我们会检查版本号是否与我们读取时的版本号相同。如果不同,说明在读取和更新之间有其他事务更新了数据,我们可以决定重试或者放弃更新。

总结

悲观锁和乐观锁是处理并发事务的两种策略。悲观锁适用于写操作多的场景,通过锁定数据来保证事务的一致性。乐观锁适用于读操作多的场景,通过版本控制来减少锁的开销,提高系统的并发性能。在实际应用中,选择哪种锁策略取决于具体的业务场景和性能要求。

附springboot,springcloudalibaba课程视频:

html 复制代码
<!-- springboot,springboot整合redis,整合rocketmq视频: -->
https://www.bilibili.com/video/BV1nkmRYSErk/?vd_source=14d27ec13a4737c281b7c79463687112

<!-- springcloudalibaba,openfeign,nacos,gateway,sso视频:-->
https://www.bilibili.com/video/BV1cFDEYWEkY/?vd_source=14d27ec13a4737c281b7c79463687112

<!-- vue+springboot前后端分离视频:-->
https://www.bilibili.com/video/BV1JLSEYJETc/?vd_source=14d27ec13a4737c281b7c79463687112

<!-- shiro视频:-->
https://www.bilibili.com/video/BV1YVUmYJEPi/?vd_source=14d27ec13a4737c281b7c79463687112
相关推荐
倔强的石头_14 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
jiayou642 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
于眠牧北2 天前
MySQL的锁类型,表锁,行锁,MVCC中所使用的临键锁
mysql
李广坤3 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
Turnip12024 天前
深度解析:为什么简单的数据库"写操作"会在 MySQL 中卡住?
后端·mysql
爱可生开源社区4 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1774 天前
《从零搭建NestJS项目》
数据库·typescript
加号34 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏4 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐5 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端