编辑帖子时可能出现的竞态条件

问题

对同一 Wiki 页面进行并发编辑可能导致意外行为。在我的案例中,两篇帖子之间的 quoted_posts 关联关系出现了错误。

当使用 quoted_posts 时(例如在 User#refresh_avatar 中),这可能导致其他问题。缺失的 quoted_posts 使得无法重新烘焙所有被引用的帖子。

可能的原因

提交 引入的警告不足以防护对帖子的并发编辑,因为该检查并非原子操作。这种情况虽然罕见,但仍可能发生。

PostRevisor#revise! 会调用 QuotedPost.extract_from(@post),如果帖子中没有任何引用,该操作会删除所有 quoted_posts。当两个编辑操作同时调用 PostRevisor#revise! 时(一个编辑添加引用帖子,另一个编辑也添加引用帖子),帖子内容最终可能保留带有引用的编辑结果,但 quoted_post 关联关系却被没有引用的编辑操作破坏了。

可能的修复方案

或许我们应该考虑在编辑帖子时获取 Redis 锁。

3 个赞

我想这是可能的,我并不强烈反对在此处添加分布式锁。棘手的是,我不想冒死锁的风险,因此我们必须极其小心。

如果并发编辑真的符合你的需求,为什么不试试共享编辑呢?

3 个赞