Rails实时编辑器数据场景下使用乐观锁的相关问题咨询
关于自定义lock_version值的问题
Rails 默认的乐观锁逻辑确实会自动对lock_version字段做自增处理,但完全支持你手动传入自定义值,不需要强制由数据库自行递增,你的使用场景是可行的,只需要注意两个前提:
- 确保编辑器返回的版本号是严格单调递增的,不会出现版本号重复、回退的情况,否则会导致锁校验逻辑失效
- 保存时Rails会自动在UPDATE语句的条件中匹配当前读取到的
lock_version旧值,匹配不到就会抛出ActiveRecord::StaleObjectError异常,你直接捕获该异常处理冲突即可
如果你需要完全接管lock_version的赋值逻辑,不想让Rails自动自增,也可以在模型中添加配置关闭默认自增行为:
class Document < ApplicationRecord # 关闭Rails默认的lock_version自动递增逻辑 def increment_lock_version end end
关于仅对指定列启用乐观锁的问题
Rails 默认的乐观锁会作用于模型的所有更新操作,只要更新任意字段都会触发锁校验和版本变更,要实现仅针对实时数据列生效的锁机制,有两种成熟的实现方案:
方案1:拆分关联表(更推荐)
将编辑器的JSON数据、lock_version字段单独放到和Document一对一关联的DocumentContent表中:
- 编辑器内容保存时操作
DocumentContent模型,触发乐观锁校验 - 其他字段更新直接操作
Document模型,完全不会触发锁逻辑
这种方案耦合度最低,后续扩展也更灵活。
方案2:重写锁触发逻辑
如果不想改表结构,Rails 6及以上版本可以直接重写模型的should_optimistically_lock?方法,仅在更新目标列时启用乐观锁:
class Document < ApplicationRecord # 仅更新editor_content列(替换为你实际的JSON字段名)时触发乐观锁 def should_optimistically_lock? changed.include?('editor_content') end end
低版本Rails可以通过around_update回调临时关闭非目标字段更新时的乐观锁配置实现相同效果。
内容的提问来源于stack exchange,提问作者domi91c
相关产品推荐
相关产品推荐

