我很难弄清楚为什么我的模特是这样的。
它有两个动作,cancel和feature,当属性已经被取消时,它就不能使用。
为了确保在取消的属性上不执行特性,我使用朱迪斯-穆特锁定属性以保持独占性,并在块中进行适当的验证。这应确保一边正在编制的记录不会同时在另一方工作:
特性动作:
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我想了解为什么有时(罕见的)属性会首先被取消,然后再出现--另一种情况是:特性和取消也可能发生,只是我还没有检测到。
请让我知道这是否是一个不好的方法,如果是的话,什么是解决这个问题的好办法。
发布于 2016-08-18 17:08:02
好吧,我想我终于找到问题了。
在修改-静音方面,我应该使用非阻塞模式来避免此类问题。
这样,如果在第一次实例中无法创建锁,则进程将被中止,并且不会产生任何问题。
我使用id (块30秒)的方式,它尝试了30秒(轮询间隔100 30 )来建立一个锁,这可能会导致这样的多个问题。示例:两个线程试图获得一个记录上的锁,最后一个线程首先建立它。
锁方法在成功获取锁时返回true,或当尝试在指定为:block的秒后失败时返回false。当0给:block时,它被设置为非阻塞模式,并立即返回false。
发布于 2016-07-07 07:20:12
当active == true和== false时,您可以调用该功能操作。这将从active == true设置为true。
然后您可以调用cancel操作。由于功能为== true,操作设置为false。
现在,active == false和== true功能。
我绘制了一个简单的状态图来显示所有可能的状态变化。例如,当活动和功能都为假时,您可以调用该功能或取消操作,但这不会起任何作用。
箭头都表示调用update_attributes的路径。圆圈代表记录中可以找到的不同的状态。
可能没有这样一种状态,即活动和功能都是假的--我看不出记录是如何构造的,所以为了完整起见,我将其包括在内。
可以很容易地看到记录的特征,但并不是活动的。

编辑:
下面是一个更新的状态图,您的if语句修复并简化了它:

因此,似乎不可能取消,然后功能。
我想到的一件事是,您没有检查来自update_attributes的返回值,以查看更新是否成功。一个失败的更新能解释观察到的行为吗?
https://stackoverflow.com/questions/38162419
复制相似问题