Spec-Zone.ru › Ruby on Rails 8.0

класс ActiveRecord::Transaction

Родитель:
Объект

Class определяет интерфейс для взаимодействия с текущим состоянием транзакции.

Он может отображаться на фактическую транзакцию/точку сохранения или представлять отсутствие транзакции.

Состояние

Мы говорим, что транзакция завершена, когда она оборачивает реальную транзакцию, которая была либо подтверждена, либо отменена.

Транзакция открыта, если она оборачивает реальную транзакцию, которая не завершена.

С другой стороны, транзакция закрыта, когда она не открыта. То есть, когда она представляет отсутствие транзакции или оборачивает реальную, но завершенную.

Вы можете проверить, открыта или закрыта транзакция, с помощью предикатов open? и closed?:

if Article.current_transaction.open?
  # We are inside a real and not finalized transaction.
end

Закрытые транзакции также являются ‘blank?’.

Callbacks

После обновления состояния базы данных иногда может потребоваться выполнить дополнительную работу или отразить эти изменения в удалённой системе, например, очистить или обновить кэш:

def publish_article(article)
  article.update!(published: true)
  NotificationService.article_published(article)
end

Вышеприведённый код работает, но имеет одну важную ошибку: он больше не работает должным образом, если его вызывать внутри транзакции, так как он будет взаимодействовать с удалённой системой до того, как изменения будут сохранены:

Article.transaction do
  article = create_article(article)
  publish_article(article)
end

Обратные вызовы, предлагаемые ActiveRecord::Transaction, позволяют переписать этот метод таким образом, чтобы он был совместим с транзакциями:

def publish_article(article)
  article.update!(published: true)
  Article.current_transaction.after_commit do
    NotificationService.article_published(article)
  end
end

В приведённом выше примере, если publish_article вызывается внутри транзакции, обратный вызов будет вызван после успешного подтверждения транзакции, а если вызывается вне транзакции, обратный вызов будет вызван немедленно.

Ограничения

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

Константы

NULL_TRANSACTION

Общедоступные методы экземпляра

after_commit() { || ... } Показать исходный код
# File activerecord/lib/active_record/transaction.rb, line 85
def after_commit(&block)
  if @internal_transaction.nil?
    yield
  else
    @internal_transaction.after_commit(&block)
  end
end

Регистрирует блок, который будет вызван после полного подтверждения транзакции.

Если в настоящее время нет открытых транзакций, блок вызывается немедленно, если транзакция не завершена, в противном случае попытка регистрации обратного вызова вызывает ActiveRecord::ActiveRecordError.

Если транзакция имеет родительскую транзакцию, обратный вызов передаётся родителю при подтверждении текущей транзакции или отбрасывается при откате текущей транзакции. Эта операция повторяется до тех пор, пока не будет достигнута внешняя транзакция.

Если обратный вызов вызывает ошибку, транзакция остаётся подтверждённой.

after_rollback(&block) Показать исходный код
# File activerecord/lib/active_record/transaction.rb, line 107
def after_rollback(&block)
  @internal_transaction&.after_rollback(&block)
end

Регистрирует блок, который будет вызван после отката транзакции.

Если в настоящее время нет открытых транзакций, блок не вызывается. Но если транзакция завершена, попытка зарегистрировать обратный вызов вызывает ActiveRecord::ActiveRecordError.

Если транзакция успешно подтверждается, но имеет родительскую транзакцию, обратный вызов автоматически добавляется к родительской транзакции.

Если вся цепочка вложенных транзакций успешно подтверждается, блок никогда не вызывается.

Если транзакция уже завершена, попытка зарегистрировать обратный вызов вызовет ActiveRecord::ActiveRecordError.

blank?()
Псевдоним для: closed?
closed?() Показать исходный код
# File activerecord/lib/active_record/transaction.rb, line 117
def closed?
  @internal_transaction.nil? || @internal_transaction.state.finalized?
end

Возвращает true, если транзакция не существует или завершена.

Также является псевдонимом для: blank?
open?() Показать исходный код
# File activerecord/lib/active_record/transaction.rb, line 112
def open?
  !closed?
end

Возвращает true, если транзакция существует и ещё не завершена.

uuid() Показать исходный код
# File activerecord/lib/active_record/transaction.rb, line 124
def uuid
  if @internal_transaction
    @uuid ||= Digest::UUID.uuid_v4
  end
end

Возвращает UUID для данной транзакции или nil, если транзакция не открыта.

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API