0

0

SQL如何根据业务场景选择悲观锁或乐观锁_写冲突频率评估

P粉602998670

P粉602998670

发布时间:2026-03-16 18:10:03

|

146人浏览过

|

来源于php中文网

原创

写冲突高时悲观锁更稳,但需精准锁行、事务要短;冲突低时乐观锁更优,需正确校验version并避免缓存复用;量化应看UPDATE影响行为0的比例,超10%需优化,超30%应切悲观锁。

sql如何根据业务场景选择悲观锁或乐观锁_写冲突频率评估

写冲突频率高时,悲观锁更稳但别硬扛

高频写冲突(比如秒杀库存扣减、订单状态强一致更新)下,SELECT ... FOR UPDATEUPDATE ... WHERE version = ? 这类操作失败率会明显上升。乐观锁靠重试兜底,但若每3次更新就有2次冲突,重试成本就压不住了——网络往返+业务逻辑重复执行+可能的副作用(如发了两次通知)。这时候直接上悲观锁更可控,但得注意:锁范围必须精准,否则容易锁表或锁住无关行。

  • WHERE 条件确保只锁目标行(避免全表扫描导致锁升级)
  • 事务尽量短,拿到锁后立刻更新,别在事务里做 HTTP 调用或复杂计算
  • MySQL 默认是 REPEATABLE READ,间隙锁可能意外锁住范围,测试时用 SELECT ... FOR UPDATE + EXPLAIN 看执行计划

写冲突低且读多时,乐观锁省资源也少阻塞

用户资料修改、文章点赞数更新这类场景,冲突概率通常低于 5%。乐观锁用 version 字段或 timestamp 做条件更新,失败时抛 OptimisticLockException 或检查 ROW_COUNT(),由应用决定重试或提示。好处是没锁等待、不占锁资源、并发吞吐高;坏处是业务层得处理“更新失败”这个分支,不能假设 UPDATE 一定成功。

  • 别把 version 放在缓存里复用——缓存可能 stale,导致误判冲突
  • UPDATE t SET count = count + 1, version = version + 1 WHERE id = ? AND version = ? 这种语句,version 必须是查询时拿到的最新值
  • PostgreSQL 的 SELECT ... FOR NO KEY UPDATE 在某些低冲突场景下可作折中,但不如乐观锁轻量

怎么量化“写冲突频率”而不是拍脑袋

不能靠“感觉”,得看真实数据。核心是统计单位时间内对同一行(或同一业务主键)的并发写请求中,实际发生冲突的比例。不是看总 QPS,而是看 UPDATE 返回影响行数为 0 的次数占比。

知我AI
知我AI

一款多端AI知识助理,通过一键生成播客/视频/文档/网页文章摘要、思维导图,提高个人知识获取效率;自动存储知识,通过与知识库聊天,提高知识利用效率。

下载
  • 在 ORM 层(如 MyBatis、Hibernate)拦截 update 操作,记录 ROW_COUNT() == 0 的比例
  • MySQL 可查 performance_schema.events_statements_summary_by_digest,过滤出带 WHERE ... version = 的语句,看 errorsrows_affected
  • 如果某接口日志里 "updated 0 rows" 出现频率 > 10%,基本说明乐观锁开始吃力;> 30% 就该切悲观锁或重构

混合用法常见但容易漏掉版本校验兜底

有些系统用悲观锁保护关键路径(如支付扣款),其他非核心字段用乐观锁更新(如用户 last_login_time)。问题常出在:开了事务用了 FOR UPDATE,结果后续更新又加了 AND version = ?——这反而多余,还可能因事务中 version 未刷新导致误失败。

  • 同一事务内,如果已用悲观锁锁定某行,后续对该行的 UPDATE 不需要再做乐观校验
  • 跨事务操作才需要乐观锁,比如“先查再改”的场景,且中间无锁保护
  • 别在悲观锁事务里调用另一个含乐观锁的 service 方法——容易形成双重校验+重复重试逻辑

真正难的不是选锁类型,而是确认哪几行算“同一业务单元”。库存、余额、状态字段经常绑在一起变,但锁粒度没对齐,冲突和死锁就都来了。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

1135

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

381

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2256

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

380

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

1743

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

587

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

441

2024.04.29

chatgpt使用指南
chatgpt使用指南

本专题整合了chatgpt使用教程、新手使用说明等等相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号