简短结论:MVCC 不能完全替代悲观锁,但在大多数读多写少、冲突不激烈的场景下,可以大幅减少甚至避免使用悲观锁。
下面分层说明。
MVCC(Multi-Version Concurrency Control,多版本并发控制)的核心思想是:
读不阻塞写,写不阻塞读
典型能力:
✅ 因此,MVCC 天然适合:
MVCC 不能防止两个事务同时修改同一行数据导致逻辑错误。
例子:
事务A:读取余额 = 100
事务B:读取余额 = 100
事务A:余额 - 50 → 写回 50
事务B:余额 - 30 → 写回 70(覆盖A)
MVCC 下:
✅ 解决方式:
SELECT ... FOR UPDATE)例如:
这些场景要求:
读到的数据,在写的时候必须还是原样
MVCC 本身不保证这一点。
MVCC 只解决数据库层面的并发可见性,不解决:
例如:
“当 A 表状态为 X,且 B 表数量 > 0 时才允许更新”
这种逻辑通常需要显式加锁。
| 方案 | 是否阻塞读 | 是否防写冲突 | 适用场景 |
|---|---|---|---|
| MVCC | ❌ 不阻塞 | ❌ 不防 | 读多写少 |
| 悲观锁 | ✅ 阻塞 | ✅ 防 | 强一致、写冲突高 |
| 乐观锁 | ❌ 不阻塞 | ✅(失败重试) | 冲突少但必须正确 |
UPDATE account
SET balance = balance - 50, version = version + 1
WHERE id = 1 AND version = 10;
BEGIN;
SELECT * FROM account WHERE id = 1 FOR UPDATE;
-- 业务逻辑
UPDATE account SET balance = balance - 50 WHERE id = 1;
COMMIT;
MVCC 替代的是“读锁”,不是“写锁”。
如果你愿意,可以告诉我你用的是 MySQL / PostgreSQL / Oracle,或者具体业务场景(库存、余额、订单),我可以直接给你更合适的方案。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。