我在before_save
中有一些逻辑,其中(仅)在满足某些条件时,我创建新行,special_number
等于数据库中的最大special_number + 1.(如果条件不满足然后我做一些不同的事情,所以我不能使用自动增量)
我担心的是,如果在第一个保存时执行第二个线程,则同时作用于此数据库的两个线程可能会选择相同的special_number
。有没有办法在before_save
和完成保存之间锁定数据库,但只在某些情况下?我知道所有保存都是在交易中发送的,这会为我做这个工作吗?
def before_save
if things_are_just_right
# -- Issue some kind of lock?
# -- self.lock? I have no idea
# Pick new special_number
new_special = self.class.maximum('special_number') + 1
write_attribute('special_number',new_special)
else
# No need to lock in this case
write_attribute('special_number',some_other_number)
end
end
答案 0 :(得分:1)
如果特殊数字总是增加1,并且您无法获得“间隙”,并且它已保存在数据库中 - 您可以使用select for update:
SELECT special_num FROM nums FOR UPDATE;
UPDATE nums SET special_num = special_num + 1;
您可以在此处阅读:select for update
请注意,它正在锁定数据库,因此如果您对特殊号码进行了大量更新,则可能会出现性能问题。
如果您不介意在特殊数字中存在间隙(如果事务失败),一种简单的方法是使用memcahced“inc”函数,因为它将非常非常快地执行:)