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
最佳答案
您可以使用 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但要注意这可能会导致死锁。
https://stackoverflow.com/questions/55518683/
相关文章:
html - 在 <input> 上使用 onChange 时未注册空间
angular - 有没有办法以编程方式触发 Angular 中的 onchange 事件? ( t
javascript - react-redux:元素类型无效
ipython - 如何在 jupyter 笔记本中插入制表符而不是自动完成?
git - 如何修复 git bash 错误异常 : STATUS_ACCESS_VIOLATION
react-native - 错误无法构建 iOS 项目。我们运行了 "xcodebuild"命令,
reactjs - 如何修复 VSCode 中的 "Expression expected. ts(