You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

加锁前已将数据库数据加载至JVM内存时分布式锁的工作机制是怎样的

现有锁机制的实际行为

你当前实现的Redis分布式锁仅能保证同一时间只有一个实例操作同一条Id对应的数据,不会出现并行修改引发的脏写,但完全解决不了「先批量查数据、后加锁处理」逻辑自带的快照过时问题,具体表现如下:

  • 锁的互斥能力正常生效:两个实例不会同时持有同一Id的锁,processData方法内的处理逻辑不会并行执行,不会出现两个实例同时写数据库导致的行级冲突或者未知异常。
  • 状态不一致场景下的执行结果完全取决于你的更新逻辑实现:
    • 如果你是直接用最开始批量查询得到的内存旧值直接覆盖数据库字段:会直接出现更新丢失问题。比如I1查询到字段值为1,修改为2后回写数据库;I2持有的内存值还是1,修改为3后直接覆盖写入,最终数据库的值为3,I1的修改完全丢失。
    • 如果你是基于数据库当前值做增量更新/条件更新,或者拿到锁后先重新查询该Id的最新数据再处理:不会出现数据错误。比如更新语句写为update message set count = count + 1 where id = ?,或者拿到锁后先根据Id从数据库查最新记录再做逻辑处理,I2拿到锁操作的就是I1修改后的最新状态,结果符合预期。
问题修复方案
  • 成本最低的优化:拿到锁之后丢弃最开始批量查询得到的旧数据,重新根据Id查询数据库最新记录再执行处理逻辑,完全规避快照过时问题。
  • 数据一致性要求高的场景:数据库表新增乐观锁版本号字段,更新时携带版本号做校验:update message set xxx = ?, version = version + 1 where id = ? and version = ?,如果执行后影响行数为0,说明数据已经被其他实例修改,直接终止当前处理即可。
  • 调度数据量较小的场景:可以把锁的时机提前到批量查询之前,同一时间只有一个实例执行这批数据的查询+处理逻辑,实现更简单,但吞吐量会降低。

内容的提问来源于stack exchange,提问作者skorpyo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 19:15:03