Rails предлагает несколько способов блокировки отдельных записей. Это описано в Руководстве по интерфейсу запроса Active Record . Однако в настоящее время я нахожусь в следующем сценарии, где блокировка существующих записей не приведет к сокращению:
У меня есть модель 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