Rails 4并发问题

ace*_*ace 3 concurrency mutex ruby-on-rails ruby-on-rails-4

我很难弄清楚我的模型表现如此的原因.

它有2个动作,取消功能,当属性已被取消时,它不应该被提供.

为确保未对已取消的属性执行某项功能,我使用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
Run Code Online (Sandbox Code Playgroud)

取消操作:

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
Run Code Online (Sandbox Code Playgroud)

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

如果这是一个糟糕的方法,请告诉我,如果是,那么解决这个问题的好方法.

Jim*_*ood 5

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

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

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

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

箭头都表示调用update_attributes的路径.圆圈表示可以在其中找到记录的不同状态.

可能没有一个状态,其中active和features都是假的 - 我没有看到记录是如何构造的所以我将其包括在内是为了完整性.

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

国家变化

编辑:

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

在此输入图像描述

因此似乎无法取消,然后功能.

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