一分钟了解乐观锁、悲观锁、共享锁、排它锁、行锁、表锁以及使用场景

简介: !! 背景:最近在各种群和博客里,又看见了什么[乐观锁]、悲观锁什么鬼的感觉很高级的词汇,于是乎今天对这几个概念进行整理一下,揭开它神秘的面纱,给大家提供一个基本参考。作为开发人员不管是用什么编程语言,我觉得这些是应该要掌握的。知其然,知其所以然。锁机制是 MySQL 中用来保证并发访问数据库时数据一致性和完整性的重要机制。在并发访问中,多个事务可能同时对同一份数据进行操作。如果不采用锁机制,就会出现数据错乱和丢失的问题。MySQL 中的锁机制主要包括以下几种类型:

1. 乐观锁

乐观锁是指在数据更新操作时,先读取数据并记录版本号,然后在更新时检查版本号是否发生变化,如果没有变化,则继续更新,否则回滚操作。乐观锁适用于并发度高的场景,因为乐观锁不会限制其他事务对数据的访问,如果数据冲突,则只需要回滚操作即可。 如果使用mybatis-plus 可以做直接配置


使用场景:适用于并发度高的场景,例如在高并发的电商网站中,多个用户同时对同一个商品进行下单操作。


示例 SQL:

-- 获取商品库存数量和版本号
SELECT stock, version FROM product WHERE id= 1;
-- 更新商品库存数量
UPDATE product SET stock = stock - 1, version = version + 1 WHERE id = 1 AND version = 1;

2. 悲观锁

悲观锁是指在数据更新操作时,先加锁,然后再更新数据,更新完成后再释放锁。悲观锁适用于并发度低的场景,因为悲观锁会限制其他事务对数据的访问,如果没有必要,就会影响并发性能。MySQL 中的悲观锁主要有共享锁和排它锁两种。


使用场景:适用于并发度低的场景,例如在银行系统中,多个用户同时对同一个账户进行转账操作。


示例 SQL:

-- 对账户进行排它锁定
SELECT balance FROM account WHERE id = 1 FOR UPDATE;
-- 用户 A 进行转账操作
UPDATE account SET balance = balance - 100 WHERE id = 1;
-- 用户 B 进行转账操作
UPDATE account SET balance = balance + 100 WHERE id = 1;
-- 释放锁
COMMIT;

3. 共享锁

共享锁是指多个事务可以共享同一份数据,但是不能同时进行更新操作。在获取共享锁之后,其他事务只能获取共享锁,不能获取排它锁。共享锁适用于读多写少的场景,可以提高并发度。

使用场景:适用于读多写少的场景,例如在新闻网站中,多个用户同时对同一篇文章进行阅读操作。

示例 SQL:

-- 对文章进行共享锁定
SELECT * FROM article WHERE id = 1 LOCK IN SHARE MODE;
-- 用户 A、用户 B 和用户 C 同时读取文章内容
SELECT title, content FROM article WHERE id = 1;
-- 释放锁
COMMIT;

4. 排它锁

排它锁是指在获取锁之后,其他事务不能获取任何类型的锁,也不能进行读取和更新操作。排它锁适用于写多读少的场景,可以保证数据的一致性和完整性。

使用场景:适用于写多读少的场景,例如在订单系统中,多个用户同时对同一份订单进行修改操作。

示例 SQL:

-- 对订单进行排它锁定
SELECT * FROM orders WHERE id = 1 FOR UPDATE;
-- 用户 A 进行修改操作
UPDATE orders SET status = 'paid' WHERE id = 1;
-- 用户 B 进行修改操作
UPDATE orders SET status = 'shipped' WHERE id = 1;
-- 释放锁
COMMIT;

5. 行锁

行锁是指在对数据的某一行进行操作时,只对该行进行锁定,其他行不受影响。行锁适用于并发度高的场景,可以提高并发性能。

使用场景:适用于并发度高的场景,例如在社交网站中,多个用户同时对同一篇文章进行点赞操作。

示例 SQL:

-- 对点赞行进行行锁定
SELECT * FROM like WHERE user_id = 1 AND article_id = 1 FOR UPDATE;
-- 用户 A 进行点赞操作
INSERT INTO like (user_id, article_id) VALUES (1, 1);
-- 用户 B 进行点赞操作
INSERT INTO like (user_id, article_id) VALUES (2, 1);
-- 用户 C进行点赞操作
INSERT INTO like (user_id, article_id) VALUES (3, 1);
-- 释放锁
COMMIT;

6. 表锁

表锁是指在对整个表进行操作时,对整个表进行锁定,其他事务不能对该表进行任何操作。表锁适用于并发度低的场景,因为表锁会限制其他事务对数据的访问,如果没有必要,就会影响并发性能。


使用场景:适用于并发度低的场景,例如在定时任务系统中,多个任务同时对同一张表进行查询操作。


示例 SQL:

-- 对整个表进行表锁定
LOCK TABLES task READ;
-- 多个任务进行查询操作
SELECT * FROM task WHERE status = 'pending';
-- 释放锁
UNLOCK TABLES;

总结

!! 锁的掌握,应该是每个开发人员必备的技能,同样锁的使用需要根据具体场景和业务需求进行调整和优化。如果锁的粒度过大或过小,都会影响并发性能和系统的稳定性。在使用锁时,需要根据具体情况选择不同的锁类型和锁粒度,以提高并发性能和保证数据安全。同时,需要注意锁的使用方式和时机,避免死锁和长时间等待的情况出现。

目录
相关文章
关于Dev 控件里 gridcontrol 的gridview 显示序号和checkbox
关于Dev 控件里 gridcontrol 的gridview 显示序号和checkbox
|
存储 Java
ArrayList自动扩容(详细篇)
ArrayList自动扩容(详细篇)
898 1
|
监控 网络协议 Unix
Linux命令-nc(端口监控、文件传输、反弹shell等)
Linux命令-nc(端口监控、文件传输、反弹shell等)
1564 0
ArrayList扩容机制
本文解析了Java中`ArrayList`的扩容机制。
331 70
|
负载均衡 Nacos 数据库
【Nacos】配置管理、微服务配置拉取、实现配置热更新、多环境配置
【Nacos】配置管理、微服务配置拉取、实现配置热更新、多环境配置
913 1
|
12月前
|
人工智能 Rust 数据挖掘
最高万元奖金|2025开源之夏x蚂蚁数据智能,12大硬核任务等你解锁
如果你想在暑期里收获:技能实战历练、大咖指导护航、高额现金奖励和荣誉证书... 那么一定不能错过 2025开源之夏!
|
网络协议 算法 网络安全
CCF推荐A类会议和期刊总结(计算机网络领域)
本文总结了中国计算机学会(CCF)推荐的计算机网络领域A类会议和期刊,这些会议和期刊代表了该领域的顶尖水平,汇聚了全球顶尖研究成果并引领前沿发展。A类期刊包括IEEE Journal on Selected Areas in Communications、IEEE Transactions on Mobile Computing等;A类会议包括SIGCOMM、MobiCom等。关注这些平台有助于研究人员紧跟技术前沿。
CCF推荐A类会议和期刊总结(计算机网络领域)
|
SQL 关系型数据库 MySQL
【Go语言专栏】使用Go语言连接MySQL数据库
【4月更文挑战第30天】本文介绍了如何使用Go语言连接和操作MySQL数据库,包括选择`go-sql-driver/mysql`驱动、安装导入、建立连接、执行SQL查询、插入/更新/删除操作、事务处理以及性能优化和最佳实践。通过示例代码,展示了连接数据库、使用连接池、事务管理和性能调优的方法,帮助开发者构建高效、稳定的Web应用。
2176 0
|
缓存 Kubernetes 网络协议
深入解析微服务架构中的服务发现机制
深入解析微服务架构中的服务发现机制
460 0
|
人工智能 供应链 安全
万字讲透:军工企业数字化转型转什么,如何做?
随着国防现代化目标的提出,军工行业景气度加速上升,企业纷纷扩产以满足新型装备加速列装的需求。航天科工集团的航天云网和中国电科的“数字电科”等项目展示了数字化转型的成效,如缩短研发周期、提高生产效率和降低成本。数字化转型对军工企业至关重要,能提升生产关系、增强竞争力,并实现生产制造和供应链的智能化。然而,转型面临挑战,包括传统认知边界、商业模式创新、技术合作共享、人才短缺和观念体制障碍。企业需制定数字化战略规划,重构组织与流程,加强网络安全,并确保人才和技术保障。案例显示,低代码平台如织信Informat可助力企业实现国产化、灵活的战略部署和数字化转型。