【发布时间】:2014-07-05 14:27:52
【问题描述】:
我有一些 Rails ActiveRecord 代码,如下所示:
new_account_number = Model.maximum(:account_number)
# Some processing that usually involves incrementing
# the new account number by one.
Model.create(foo: 12, bar: 34, account_number: new_account_number)
此代码本身运行良好,但我有一些由 DelayedJob 工作人员处理的后台作业。有两个工人,如果他们都开始处理一批处理此代码的作业,他们最终会创建具有相同 account_number 的新 Model 记录,因为在找到最大值和创建新记录之间存在延迟更高的帐号。
目前,我已通过在模型表中添加数据库级别的唯一性约束来解决此问题,然后通过重新选择最大值来重试,以防此约束触发异常。
但是感觉就像是黑客攻击。
将数据库级别的自动递增添加到account_number 列不是一种选择,因为分配 account_number 不仅仅需要递增。
理想情况下,我想锁定有问题的表以供阅读,因此在我完成之前,没有其他人可以对该表执行最大选择查询。但是,我不知道该怎么做。我正在使用 Postgresql。
【问题讨论】:
-
约束不是黑客,手动锁定表是黑客。
-
用
EXCLUSIVE锁定表,这样可以读取数据
标签: sql ruby-on-rails postgresql activerecord locking