行锁如何影响并发“修改再查询”场景

两个并发事务对同一行数据执行"修改-再查询"操作。

在关系型数据库中,结果取决于事务隔离级别。

以 MySQL InnoDB(默认 Repeatable Read)为例,假设表 A 有一行 id=1, value=100。

时间线模拟

时间 事务1(用户A) 事务2(用户B)
T1 BEGIN;
T2 BEGIN;
T3 SELECT * FROM A WHERE id=1; → 看到 value=100
T4 SELECT * FROM A WHERE id=1; → 看到 value=100
T5 UPDATE A SET value=200 WHERE id=1;
T6 UPDATE A SET value=300 WHERE id=1; (会被阻塞,等待事务1提交或回滚)
T7 SELECT * FROM A WHERE id=1; → 看到 value=200 (仍在等待锁)
T8 COMMIT; (事务2获取锁,继续执行)
T9 UPDATE 实际执行(覆盖为300)
T10 SELECT * FROM A WHERE id=1; → 看到 value=300
T11 COMMIT;

最终结果

  • 数据库中最终值 = 300(后提交的事务覆盖先提交的)

  • 用户A 在他自己的事务内,修改后查询到 200

  • 用户B 在他自己的事务内,修改后查询到 300

不同隔离级别下的差异

隔离级别 事务2更新时是否阻塞 事务1提交后,事务2再次查询能否看到事务1的修改? 可能问题
读未提交(Read Uncommitted) 不阻塞(可能脏写) 能,但会读到未提交数据 脏读、脏写
读已提交(Read Committed) 阻塞(行锁) 能,事务2更新前会读到已提交的最新值(但它的查询在T10看到300,因为已提交) 不可重复读
可重复读(Repeatable Read,MySQL默认) 阻塞 不能,事务2内多次查询结果一致(快照读) 幻读(部分情况)
可串行化(Serializable) 阻塞 + 间隙锁 不能,且性能最差 无并发问题

关键结论

  1. 不会出现"丢失更新"(因为行锁阻塞了并发更新)。

  2. 用户各自看到自己的修改结果,符合预期。

  3. 最终数据以后提交的事务为准(丢失了用户A的修改),除非应用层实现乐观锁(如版本号)。

  4. 在 Repeatable Read 下,事务2即使在T9之后重新查询整行,看到的仍是它修改后的300,不会看到200,保证了可重复读。

实际开发建议

  • 这种场景下,如果不允许覆盖(比如余额扣减),应该使用:

    sql 复制代码
    UPDATE table SET value = new_value WHERE id=1 AND value = old_value;
    或加版本号:
    
    UPDATE table SET value = new_value, version = version+1 WHERE id=1 AND version = old_version;
  • 如果必须保证业务顺序,可以考虑 SELECT ... FOR UPDATE(当前读,加行锁)在查询时就锁定。

相关推荐
骑着蜗牛撵大象32720 小时前
MySQL 8.0 迁移后 SQL 变慢:执行计划里 3 类被忽略的成本差异
android·数据库·sql·mysql·优化器·执行计划
zhengfei6111 天前
Go-fastdfs /reload 未授权访问: 有效PoC
数据库·sql
大维1 天前
DBX 实测:从 SQLite 查询到 MiniMax-M3 自然语言生成 SQL
数据库·sql·sqlite
景煜拾年1 天前
InnoAI SQL 助手
运维·数据库·笔记·sql
Decay__2 天前
22_MySQL 运维自动化平台 —— 部署编排 + 监控 + 巡检 + 告警 + 工单闭环一体化
运维·数据库·sql·mysql·架构
Decay__2 天前
21_MySQL 优化案例集 —— 慢 SQL 优化、索引重构与参数调整收益对比
运维·数据库·sql·mysql·架构
挖掘狂人2 天前
MySQL 深分页优化:limit 100000, 10 慢在哪,怎么救
后端·sql·mysql
codigger2 天前
MySQL 深分页优化:limit 100000, 10 慢在哪,怎么救
数据库·sql·mysql·程序员
Francek Chen2 天前
【大数据处理与分析】数据仓库Hive:09 Hive 编程实践
大数据·数据仓库·hive·hadoop·sql
麦壳饼2 天前
SonnetDB 5.0 正式发布:增强 SQL 与事务,开放九模型 MCP 读写
数据库·人工智能·sql·sonnetdb