Делает ли рельсы откат, если я использую begin ... rescue? - PullRequest
13 голосов
/ 23 апреля 2010

Я бы хотел добавить блок begin ... rescue к одному из моих методов создания контроллеров, чтобы записать лучшую информацию и создать правильное сообщение об ошибке для возврата клиенту. Спасение каким-либо образом «прерывает» процесс отката?

Я предполагаю, что рельсы автоматически делают откат. Когда это происходит? Это уже произошло к тому времени, как я попал в пункт о спасении?

Я использую mySQL на Dreamhost и думаю, что они используют innoDB.

Ответы [ 4 ]

20 голосов
/ 10 января 2013

Я экспериментировал с этим. Похоже, что если ваше спасение перехватит исключение, которое вызвало бы откат, часть транзакции, которая уже произошла, будет зафиксирована. В моем случае я хочу, чтобы база данных откатилась до того состояния, которое было до начала транзакции, но я все еще хочу обработать исключение.

Я закончил с этим:

self.transaction do
  first_operation
  begin
    operation_that_might_violate_db_constraint
  rescue ActiveRecord::RecordNotUnique
      #deal with the error
      raise ActiveRecord::Rollback #force a rollback
  end
end

Часть raise ActiveRecord::Rollback обеспечивает полное откат транзакции. Без этого изменения из first_operation в конечном итоге будут зафиксированы.

ActiveRecord :: Rollback - это особый вид исключений, который не всплывает над уровнем транзакции, поэтому вы не получите необработанное исключение, которое отображает страницу ошибки.

Я не уверен, что это золотой стандарт, но похоже, что он работает.

0 голосов
/ 07 сентября 2015

Откат не будет обработан.

например:

create_table "helps", :force => true do |t|
    t.string   "title",                           :null => false
    t.text     "content"
end

#Rails console
Help.transaction do
  Help.create! title: "aaa"
  begin
    Help.create! content: "111"
  rescue
    p "create error."
  end
  Help.create! title: "bbb"
end

#get this
>> "create error."
Help.count
>> 2
0 голосов
/ 16 апреля 2014

Вы также можете попробовать мой ответ для отката, отлова и рендеринга для вашего метода создания, используя ActiveRecord :: Base.transaction : - Нажмите здесь

Спасибо

0 голосов
/ 23 апреля 2010

Простого использования begin ... rescue недостаточно для отката транзакции. Вам необходимо использовать:

ModelName.transaction do 
end

Это делается явно при сохранении вызова, чтобы все ваши обратные вызовы выполнялись вместе Какие исключения вы ловите в своем блоке спасения? На что вы реагируете? Что за ошибки?

...