Skip to content

061. Version 字段、更新策略与锁选择

学习目标

这一节讨论乐观锁里的 version 字段是否要做成通用字段,并比较几种更新策略。

学完后,你应该能理解:

  • version 字段为什么不一定适合做成标准字段;
  • 按需更新和全量更新有什么区别;
  • 全量更新为什么更需要互斥控制;
  • 悲观锁和乐观锁的取舍;
  • 为什么后端代码看起来简单但责任更重。

version 不一定是标准字段

乐观锁通常需要 version 字段。

但它不一定要放进所有表的基础字段里。

原因是项目里很多更新是按需更新。

只有真正需要并发控制的表,才需要 version。

例如库存、积分、金额、项目已花费金额等字段更新,才更适合加 version。

普通信息表不一定需要。

按需更新

按需更新是指:前端只提交被修改的字段。

例如只改备注:

json
{
  "id": "001",
  "remark": "new remark"
}

后端生成 SQL 时也只更新 remark

没有提交的字段,不会被写入 SQL。

这样 A 用户改备注、B 用户改标题时,两个修改互不覆盖。

全量更新

全量更新是指:更新时把整条记录的所有字段都提交上来。

它的风险是:用户没有修改的旧字段,也会被一起写回数据库。

例如 A 改了字段一,B 改了字段二。

如果两边都是全量更新,后提交的人可能把先提交的人改动覆盖掉。

这时就很需要 version 做互斥控制。

JS/Python 的优势

JS 和 Python 都很容易遍历对象或字典。

后端可以根据请求体里实际出现的字段生成更新语句。

这让按需更新更自然。

某些后端栈如果默认生成全量更新,要实现按需更新会麻烦一些。

所以不同语言和 ORM 的写法,会影响并发控制策略。

冲突字段如何处理

按需更新不是没有冲突。

如果 A 和 B 同时修改同一个字段,最后仍然只能保留一个结果。

但这类冲突通常可以接受:最后提交的人覆盖前一个人。

真正危险的是金额、库存、计数器这类需要“基于旧值计算新值”的字段。

这类字段不能简单最后写入为准。

悲观锁回顾

悲观锁是在操作数据前先锁住数据。

它的特点是:

  • 数据安全性强;
  • 实现简单;
  • 数据库阻塞明显;
  • 索引失效时可能锁表;
  • 适合低并发、高一致性场景。

如果业务像银行核心账务一样,写操作不算高频,但正确性极高,悲观锁仍然有价值。

乐观锁回顾

乐观锁不在读取时加锁。

它在更新时判断 version 有没有变化。

如果变化了,就说明数据被别人改过,需要重新读取和重试。

它的特点是:

  • 并发性能更好;
  • 数据库阻塞更少;
  • 代码更复杂;
  • 后端会承担重试压力;
  • 适合冲突概率可控的场景。

压力放在哪里

悲观锁把等待压力放在数据库。

用户排队时,数据库锁住记录,其他请求等待。

乐观锁把等待压力放在后端。

后端先执行业务逻辑,更新失败后再重试。

数据库压力小一些,但后端 CPU、内存和请求生命周期会增加。

后端责任更重

前端 bug 很多时候是展示错误或参数错误。

后端 bug 可能直接影响金额、库存、优惠券、订单、审批状态。

所以后端逻辑看起来不一定更复杂,但责任更大。

AI 生成代码后,开发者仍然要判断并发、安全、事务和异常边界。

不能只看“本地跑通”。

这一节的重点

这一节把 version 字段和锁策略放回业务场景里看。

你需要记住:

  • version 不必变成所有表的标准字段;
  • 按需更新能减少字段覆盖;
  • 全量更新更依赖互斥控制;
  • 金额、库存、计数器必须考虑并发;
  • 悲观锁压数据库,乐观锁压后端;
  • 让 AI 写代码前,你要先知道该选哪类方案。

AI Agent 课程学习文档。