Rails提供了几种锁定单个记录的方法。 Active Record Query Interface guide中对此进行了描述。但是,我目前处于以下情况,锁定现有记录不会成功:
我有一个 Letter 模型,该模型具有可选的 mailing_nr 属性。对于邮件,我将获取最大的 mailing_nr 并添加一个。然后,在事务中创建一堆字母,因为所有字母应同时保存,或者根本不保存。
想象一下这样一种情况:两个用户在同一时间生成邮件。它们都将获取最高的 mailing_nr (我将以6
为例)。当两个进程都保存其记录时,它们将以相同的 mailing_nr 结尾。
如何防止上述情况?我想锁定整个表,以防止其他进程进行读写。但是我不知道有任何Rails方法可以做到这一点。
这是我的代码示例:
# app/models/letter.rb
def self.create_mailing(template, report, options = {})
options = options.dup
options[:mailing_nr] = (Letter.maximum(:mailing_nr) || 0) + 1
letters = nil
transaction do
letters = report.fetch_records.map do |record|
new_with_template(template, record, options).tap(&:save!)
end
end
letters
end
答案 0 :(得分:0)
您可以像这样使用Rails Lock:
letter = Letter.find(1)
letter.with_lock do
#Do whatever you want, You have only single access here. No two persons can access this at a time
end
注意请务必仔细阅读提供的链接,因为您可能会在此处找到不同的方法,这可能会更好地解决您的特定问题。
更新:您可以使用this gem,但会被警告可能导致死锁。