Ruby: заблокированный объект остается заблокированным, если внутри него возникает исключение? - PullRequest
0 голосов
/ 02 октября 2018

Я использую with_lock, чтобы заблокировать блок инструкций, куда я собираюсь позвонить update_all.Если в блоке возникает исключение, заблокированный объект остается заблокированным?

Например, validator: handle_conflict вызовет исключение ActiveRecord::StaleObjectError, разблокирует ли with_lock блокировку?Если он не снимает блокировку, как снять блокировку при возникновении исключения?

attr_accessible :original_updated_at

def original_updated_at
   @original_updated_at || updated_at.to_f
end

validate :handle_conflict, only: :update_all


  def set_total_and_buckets_used
    begin
      /////

      else
        self.with_lock do
          self.reload
          attributes["updated_at"] = Time.now.utc
          Product.where(:id => self.id).update_all(attributes)
          self.attributes = attributes
        end
      end
    rescue ActiveRecord::StaleObjectError => e
      if tries < MAX_RETRIES
        tries += 1
        sleep(1 + tries)
        retry
      else
        raise Exception.new(timeout.inspect)
      end
    end
    attributes
  end


  def handle_conflict
    if self.updated_at.to_f > original_updated_at
      @original_updated_at = nil
      raise ActiveRecord::StaleObjectError.new("Car is changed while you were editing")
    end
  end

1 Ответ

0 голосов
/ 02 октября 2018

Если вы посмотрите на реализацию , вы увидите, что with_lock превращает ваш блок в транзакцию.Таким образом, когда в вашем блоке возникает исключение, ваша транзакция откатывается и ваша блокировка снимается.

Кстати:

  • блокировка вашей записи гарантирует, что у вас не будетиметь дело с StaleObjectError.
  • Я не думаю, что ваш код работает, почему бы вам просто не обновить вашу модель:

self.with_lock do update_your_attributes self.save end

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...