RoR应用新标签页打开记录触发ActiveRecord::StaleObject错误解决方案咨询
RoR 多标签页触发会话存储
ActiveRecord::StaleObject异常解决方案 以下方案均无需修改现有会话表结构、不影响历史会话数据,改动复杂度低:
- 方案1:会话存储模型单独关闭乐观锁(最推荐,改动最小)
乐观锁对会话存储场景的必要性极低:会话更新即使出现覆盖,对业务的影响几乎可忽略,反而乐观锁会因多标签页并发请求触发不必要的报错。
找到你的会话存储对应的ActiveRecord模型(通常是Session类,也可能自定义命名),添加一行配置即可:
该配置会直接关闭该模型的乐观锁校验,不会删除已有self.locking_column = nillock_version字段,也不影响其他模型的乐观锁逻辑。 - 方案2:新增异常重试逻辑(适合不想关闭乐观锁的场景)
会话更新的冲突都是瞬态的,新增重试机制可以解决绝大多数冲突问题,在Rails初始化目录下新建config/initializers/session_store_patch.rb,添加如下逻辑:
可根据实际情况调整重试次数,建议不超过3次避免无限循环。ActiveRecord::SessionStore::ClassMethods.module_eval do def update_session(env, session_id, data, options) retries ||= 0 super rescue ActiveRecord::StaleObjectError retries += 1 retry if retries < 3 raise end end - 方案3:优化会话更新触发逻辑,减少无意义更新
默认Rails每次请求都会更新会话的最后访问时间,即使会话内容没有任何变化,你可以关闭自动更新访问时间的逻辑,或者调整为仅当会话内容发生变更时才触发数据库更新,从根源降低冲突概率。
配置方式:在config/initializers/session_store.rb中添加:
注:该配置在Rails 6.1+版本原生支持,低版本需要自行适配轻量补丁。Rails.application.config.session_store :active_record_store, expire_after: 24.hours, skip_session_update_if_unchanged: true
内容的提问来源于stack exchange,提问作者Dovah
相关产品推荐
相关产品推荐

