Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL乐观锁和悲观锁的区别

MySQL中的乐观锁和悲观锁的区别及说明

作者:篱笆院的狗

这篇文章主要介绍了MySQL中的乐观锁和悲观锁的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

在 MySQL 中,乐观锁悲观锁是两种不同的并发控制机制,用于解决多用户/事务同时操作数据时的冲突问题。

它们的核心理念和实现方式有显著区别:

1. 悲观锁(Pessimistic Locking)

核心思想

假设数据会被频繁修改,因此提前对数据进行加锁,防止其他事务访问,直到当前事务完成操作并释放锁。

实现方式

显式加锁:通过 SQL 语句主动申请锁。

SELECT ... FOR UPDATE

(在事务中锁定选中的行,阻止其他事务修改或加锁)

SELECT ... LOCK IN SHARE MODE

(允许其他事务读,但阻止写操作)

隐式加锁:数据库自动管理(如 MySQL 的 InnoDB 引擎默认使用行级锁)。

适用场景

示例

START TRANSACTION;
-- 锁定用户账户余额(排他锁)
SELECT balance FROM accounts WHERE user_id = 1 FOR UPDATE;
-- 执行扣款操作
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
COMMIT;

优点:

缺点:

2. 乐观锁(Optimistic Locking)

核心思想

假设数据冲突较少发生,因此不加锁,而是在更新时检查数据是否被修改过。若被修改过,则拒绝操作或重试。

实现方式

UPDATE table 
SET 
  column = new_value, 
  version = version + 1 
WHERE 
  id = 1 AND version = old_version;

适用场景

示例

-- 初始查询(获取当前版本号)
SELECT balance, version FROM accounts WHERE user_id = 1;

-- 更新时检查版本号
UPDATE accounts 
SET 
  balance = balance - 100, 
  version = version + 1 
WHERE 
  user_id = 1 AND version = 1; -- 假设旧版本号是1

-- 如果受影响行数=0,说明版本已过期,需重试或报错

优点:

缺点:

3. 对比总结

特性悲观锁乐观锁
加锁时机操作前加锁操作后验证
实现复杂度依赖数据库机制需应用层配合(如版本号)
并发性能较低(锁竞争)较高(无锁)
适用场景高竞争、强一致性低竞争、最终一致性
典型问题死锁、性能瓶颈版本冲突、重试逻辑

4. MySQL 中的实际选择

根据业务场景选择:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文