首页 >> 基础教程
mysql乐观锁和悲欢锁
MySQL中的乐观锁和悲观锁是解决数据库并发访问冲突的两种核心策略,它们在设计理念和实现方式上有显著区别:
一、悲观锁(Pessimistic Locking)
核心理念:假设冲突必然发生,操作数据前先加锁独占资源。
实现方式:通过MySQL的锁机制(如SELECT ... FOR UPDATE
或SELECT ... LOCK IN SHARE MODE
)实现。
适用场景:写操作频繁、冲突概率高的场景(如账户扣款、库存争抢)。
START TRANSACTION; -- 锁定查询到的行(其他事务无法修改) SELECT * FROM products WHERE id = 1 FOR UPDATE; -- 执行业务逻辑(如扣减库存) UPDATE products SET stock = stock - 1 WHERE id = 1; COMMIT;
特点:
优点:保证强一致性,避免并发冲突。
缺点:
加锁增加系统开销,降低并发性能。
可能引发死锁(需事务及时提交/回滚)。
锁粒度控制不当易导致性能问题(如行锁升级为表锁)。
二、乐观锁(Optimistic Locking)
核心理念:假设冲突很少发生,提交操作时再检测冲突。
实现方式:通过版本号(version
)或时间戳字段实现无锁并发控制。
适用场景:读多写少、冲突概率低的场景(如评论更新、配置修改)。
-- 先查询当前版本号 SELECT stock, version FROM products WHERE id = 1; -- 执行业务逻辑(内存中计算新值) -- 更新时校验版本号 UPDATE products SET stock = stock - 1, version = version + 1 WHERE id = 1 AND version = 旧版本号; -- 检查是否更新成功(影响行数 > 0)
特点:
优点:
无锁设计,并发性能高。
避免死锁风险。
缺点:
冲突时需重试或回滚,增加业务逻辑复杂度。
不适用高冲突场景(频繁重试可能降低性能)。
存在ABA问题(可通过递增版本号解决)。
三、关键对比
特性 | 悲观锁 | 乐观锁 |
---|---|---|
冲突假设 | 必然发生 | 很少发生 |
实现方式 | 内置锁机制(FOR UPDATE ) | 版本号/时间戳字段 |
加锁时机 | 操作前加锁 | 提交时检查 |
性能影响 | 高开销(锁竞争) | 低开销(无锁) |
适用场景 | 高并发写、强一致性要求 | 低冲突、高并发读 |
复杂度 | 数据库层控制,业务逻辑简单 | 需业务层处理重试 |
典型用例 | 库存扣减、金融交易 | 更新用户信息、统计计数 |
四、如何选择?
悲观锁适用:
事务涉及多表复杂更新。
业务逻辑无法容忍重试(如支付交易)。
冲突频率高(如秒杀场景)。
乐观锁适用:
读操作远多于写操作。
冲突概率低(如CMS内容编辑)。
系统要求高吞吐量(如日志记录)。
乐观锁以版本检测换性能,悲观锁以提前加锁保安全。根据业务场景的冲突概率、一致性要求及性能需求权衡选择,必要时可组合使用(如读用MVCC、写用悲观锁)。
最新文章
mysql分页问题2025-08-04
千万数据先insert和先建索引哪个快2025-08-04
MySQL 中大小表关联查询如何优化2025-08-04
sql技巧-每个班年龄排前两名的人2025-08-03
MySQL 导致 cpu 飙升的话,要怎么处理呢?2025-07-29
MySQL 中为千万级大表添加字段2025-07-29
mysql中百万级别以上的数据如何删除2025-07-29
分库分表带来的问题2025-07-29
mysql中常用的分库分表中间件有哪些2025-07-29
mysql不停机扩容2025-07-29