拿下技术面上传简历

MySQL InnoDB,隔离级别 REPEATABLE READ。下单扣库存的代码是这样写的:先在事务里执行 SELECT stock FROM product WHERE id=1(普通 SELECT,不带 FOR UPDATE),应用层判断返回值 > 0,然后执行 UPDATE product SET stock = 5 WHERE id=1 把算好的值写回去。压测时这个逻辑出现了超卖。请解释为什么在 RR 下还会超卖,并给出至少两种修复方案,分别说明它们的代价。

工程与系统设计数据与存储3-5 年知识点 1 个

面试官在考什么

判断候选人是否真正分清快照读与当前读、锁什么时候加,而不是背「RR 能防超卖」。

事务

回答框架 · 前两步

  1. 根因:RR 下的普通 SELECT 是快照读,直接读 MVCC 版本、不加锁,读到的是事务开始时的旧值;应用层基于这个旧值做判断,再写入一个固定值,属于典型的丢失更新(写覆盖)。并发事务各自读到 stock=10,各自写回 9。
  2. 修复一(推荐):把判断下推到 UPDATE 的 WHERE 条件,写成 SET stock = stock - 1 WHERE id=1 AND stock >= 1,用 UPDATE 自身的当前读 + 行 X 锁把同一行的并发串行化,再用 affected rows 是否为 1 判断成功;注意不能把 affected rows=0 和语句报错混为一谈。

还有 3 条答案要点、 3 层追问、 5 个常见坑, 以及针对你简历的追问路径,在定制报告里。

上传简历,生成我的题库先看示例报告

同一能力域的其他题