VP导航 VP导航
首页 提交网址

资讯文章 资讯 · NEWS

两个人同时改一条条目:事务隔离级别、乐观锁,和目录站的并发写入

2026-10-24 约 1,735 字 预计阅读 4 分钟 yiyunkj

两个人同时改一条条目:事务隔离级别、乐观锁,和目录站的并发写入 两

先把结论放在前面:大多数「改了半天没生效」不是数据库坏了,是读改写三步中间被别人插了一脚。应用层往往读出来、在内存里拼好、再整体写回,这三步之间如果有另一个事务成功提交,你的写回就把它覆盖了,双方都不报错。

这就是所谓的丢失更新(lost update),它最麻烦的地方在于没有异常、没有日志、过了几天才发现数据不对。

事务隔离级别与乐观锁方案的对照示意

图片来源:网络,版权归原作者所有,侵权请联系删除

InnoDB 默认级别意味着什么

MySQL 官方文档写得很清楚:InnoDB 默认隔离级别是 REPEATABLE READ(可重复读),同一个事务里的一致读,读的是第一次读建立的快照。

真正影响并发写入的是后半句:在这个级别下,加锁读(FOR UPDATE / FOR SHARE)、UPDATE、DELETE 除了锁住命中的索引记录,还会锁住索引范围之间的间隙(间隙锁和 next-key 锁)。目的是防止别的事务往你扫过的范围里插入「幻行」。

这带来一个常被误判的现象:一条看起来只改一行的 UPDATE,实际锁住的是一段范围。尤其是 WHERE 条件走不到索引时,扫描过程会把整张表的记录和间隙都锁上,其他写入全堵在后面。

换成 READ COMMITTED 会松什么

READ COMMITTED 下,每次一致读都取自己的新快照,间隙锁在普通搜索和索引扫描中关闭,只保留外键检查和重复键检查。不匹配的行在评估完 WHERE 后立刻释放记录锁,半一致读也让 UPDATE 少等不少。

行为REPEATABLE READREAD COMMITTED
一致读快照事务首读建立每条语句各自建立
间隙锁(普通范围扫描)有无
不匹配行的记录锁释放事务结束才放评估后立即释放
死锁概率相对高明显降低但仍有

代价要写明白:READ COMMITTED 只支持行格式 binlog,设成 MIXED 服务端会自动切回行格式。另外纯粹为了解决死锁而降级,往往治标——根因通常是 SQL 走的路径和访问顺序。

死锁是怎么被判出来的

InnoDB 会自动检测死锁,回滚它认为代价较小的那个事务,被踢的一方拿到 ERROR 1213。要看清楚发生了什么:

SHOW ENGINE INNODB STATUS\G

重点看 LATEST DETECTED DEADLOCK 段,每个事务会列出它持有的锁和在等的锁。锁模式那几行是线索:

模式字串含义
locks rec but not gap纯记录锁,没有间隙部分
带 supremum 伪记录行的 next-key 锁延伸到索引末端的 next-key 锁
insert intention waiting插入意向锁在等别人的间隙锁

想把每一次死锁都记进错误日志而不是只看最后一次,开这个:

SET GLOBAL innodb_print_all_deadlocks = ON;

乐观锁怎么写才算数

目录站条目编辑这种「读得早、写得晚」的场景,悲观锁会把编辑页挂锁挂到用户点保存,不合适。更常见的做法是版本号:

UPDATE items
   SET intro = ?, version = version + 1, updated_at = NOW()
 WHERE id = ? AND version = ?;

三条要点缺一不可:

第一,必须检查受影响行数。返回 0 说明期间有人改过,这时要重新读取再提示用户,而不是默默当作成功。

第二,读写要用同一个版本号,前端表单里带上原 version,别在提交时现查。

第三,更新时间和版本同时推进,方便排查——谁在什么时候抢先一步,日志里看得出来。

批量任务那边的另一套思路

巡检任务几千条批量更新,如果每条都走「先查再 UPDATE」,一次任务就是几千次往返,还会和人工编辑抢锁。更稳的做法:

一是固定顺序,按主键升序处理,减少互相等待成环的机会。

二是拆小批次,每批几百条,批间留间隔,失败时重跑那一批就行,不用整批回滚。

三是能用单条 UPDATE 完成的,不要用读改写。比如计数类字段直接 SET n = n + 1,数据库自己保证原子。

自查清单

把 UPDATE 和 DELETE 的 WHERE 条件逐个对着索引查一遍执行计划;确认有没有走全表扫描;高危写入是否在同一个事务里既做锁定读又做普通 SELECT(官方明确不建议在 RR 下混用这两类语句,因为两者看到的数据状态不同);以及最重要的——给每条会长期跑的写入语句一个「谁改了同一行」的可观测入口,问题出现时能定位到人而不是猜。

本文标签 事务隔离级别 乐观锁 并发写入冲突
← 上一篇 页面返回时为什么会闪一下:bfcache 的准入条件 下一篇 → 表涨到几百万行之后:分区、归档,和那些越跑越慢的查询

— 本文完 —

提交网址

发现好站,欢迎自荐收录

站内搜索

站点统计

  • 今日审核0
  • 已收录站点3744
  • 正常访问3738
  • 失联站点6
  • 累计访问175

网站分类

  • AI工具 0
    AI对话0 AI绘画0 AI写作0 AI编程0 AI音视频0 AI办公效率0
  • 开发编程 0
    前端开发0 后端开发0 移动开发0 开源与代码托管0 数据库0 开发文档与教程0
  • 设计素材 0
    UI设计0 图标素材0 免费图库0 字体下载0 配色工具0 设计模板0
  • 站长工具 0
    网站统计0 SEO工具0 域名与主机0 收录提交0 建站程序0 运维监控0
  • 学习教育 0
    编程教程0 语言学习0 职业技能0 公开课与慕课0 考试题库0 中小学教育0
  • 生活服务 0
    交通出行0 外卖点餐0 房产租房0 医疗健康0 政务办事0 快递物流0
  • 影音娱乐 0
    影视观看0 音乐音频0 游戏资源0 短视频直播0 小说阅读0
  • 电商购物 0
    综合商城0 比价工具0 导购返利0 二手交易0 团购优惠0
  • 综合其他 1
    实用工具0 资源合集0 小众站点0 个人博客0 论坛社区0
  • 新闻资讯 0
    科技资讯8 财经媒体1 行业动态0 社会热点0 综合门户0
  • 资讯文章 370

最新收录

  • 车机屋-专业车机系统研究平台,海量正
  • 通义千问
  • 阿里巴巴矢量图标库
  • DeepSeek
  • Kimi
  • 快看漫画
  • 苏宁易购
  • 埋点为什么总对不上数:目录站的事件模

浏览排行

  1. 满分作文网 6
  2. Let's Enhance 3
  3. 淘菜菜 3
  4. MasterClass 3
  5. TypeScript 中文网 3
  6. Zhengziying 3
  7. 得意生活 3
  8. 镇江网友之家 3

联系我们

bQ:12345678

电话:400-8888-888

邮箱:admin@example.com

时间:09:00-21:00

友情链接

车机屋·焊锡条·探兔AI导航·静电测试仪·大学生联盟

关于我们|广告合作|隐私条款|网站地图

原ICP备00000000号-1,@2026

由 Z-BlogPHP 驱动