Spec-Zone.ru › Ruby on Rails 7.2

класс ActiveRecord::Transaction

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

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

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

Состояние

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

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

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

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

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

Закрытые транзакции также являются «пустыми».

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