我很难弄清楚为什么我的模型表现得像这样。

它有 2 个 Action , 取消 功能 ,当属性已经被取消时,它不应该被展示。

为了确保不会对取消的属性执行某个功能,我使用 Redis-Mutex 锁定该属性以获得排他性并在块内进行适当的验证。这应确保在一侧编制的记录不会同时在另一侧编制:

功能操作:

mutex = RedisMutex.new(record_to_feature, block: 30, sleep: 0.1)
if mutex.lock
    record_to_feature = record_to_feature.reload

    if record_to_feature.reload.active?
        record_to_feature.reload.update_attributes(featured: true)
    end
    mutex.unlock
end

取消操作:
mutex = RedisMutex.new(record_to_cancel, block: 30, sleep: 0.1)
if mutex.lock
    record_to_cancel = record_to_cancel.reload

    if !record_to_cancel.reload.featured?
        record_to_cancel.reload.update_attributes(active: false)
    end
    mutex.unlock
end

我想了解有时(罕见)属性首先被取消然后被推荐是如何可能的 - 另一种方式:特征然后取消也可能发生,只是我没有检测到它。

请让我知道这是否是一种不好的方法,如果是,那么解决此问题的好方法是什么。

最佳答案

当 active == true 和 features == false 时,您可以调用功能操作。这会将 features 设置为 true,因为 active == true。

然后你可以调用取消操作。由于 features == true,因此 action 设置为 false。

现在,active == false 和 features == true。

我画了一个简单的状态图来显示所有可能的状态变化。我没有包括无操作状态更改,例如,当 active 和 features 都为 false 时,您可以调用该功能或​​取消操作,但这不会做任何事情。

箭头都表示调用 update_attributes 的路径。圆圈代表可以找到记录的不同状态。

可能不存在事件和精选都为假的状态——我看不到记录是如何构建的,因此我将其包括在内以保持完整性。

很容易看出记录是如何被展示的,但又不是活跃的。

ruby-on-rails - Rails 4 并发问题-LMLPHP

编辑:

这是一个更新的状态图,您的 if 语句已修复并简化:

ruby-on-rails - Rails 4 并发问题-LMLPHP

所以似乎不可能取消,然后功能。

我发生的一件事是您没有检查 update_attributes 的返回值以查看更新是否成功。失败的更新能否解释观察到的行为?

关于ruby-on-rails - Rails 4 并发问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38162419/

10-13 02:10