2024/04/03分のコミットです。
CHANGELOGにのったコミットは以下の通りです。
ActiveRecord::Base.transaction
now yields anActiveRecord::Transation
object.- Add
ActiveRecord::Base.current_transaction
. - Add
ActiveRecord.after_all_transactions_commit
callback.
activejob/CHANGELOG.md
ActiveRecord
をActionRecord
にタイポしている箇所があったのを修正しています。
Allow to register transaction callbacks outside of a record
Active Recordの修正です。
recordの外側からtransaction callbacksを登録出来るよう対応しています。このコミットでは、左記の為に下記の対応を行っています。
まず、transactionのcommit後に実行するcallbackを登録する為のActiveRecord.after_all_transactions_commit
を追加しています。
def publish_article(article) article.update(published: true) ActiveRecord.after_all_transactions_commit do PublishNotificationMailer.with(article: article).deliver_later end end
上記の例の場合、PublishNotificationMailer
はtransactionの外側から呼ばれたか、transactionがコミットされた場合に実行されます。transactionがrollbackされた場合は実行されません。
次に、現在のtransactionを取得する為のActiveRecord::Base.current_transaction
を追加しています。こちらもtransactionへのcallbackを登録しやすくする為。
Article.current_transaction.after_commit do PublishNotificationMailer.with(article: article).deliver_later end
最後に、 ActiveRecord::Base.transaction
をActiveRecord::Transation
objectをyieldするよう修正しています。こちらもtransactionへのcallbackを登録しやすくする為。
Article.transaction do |transaction| article.update(published: true) transaction.after_commit do PublishNotificationMailer.with(article: article).deliver_later end end
Implement Active Job enqueue_after_transaction_commit
Active Jobの修正です。
Active Recordのtransaction内でActive Jobのenqueueが行われた場合に、自動でtransaction commit後にjobのenqueueを行うよう修正しています。
Topic.transaction do topic = Topic.create(...) NewTopicNotificationJob.perform_later(topic) end
transactionがコミットされる前にenqueueされたjobが、job実行プロセスにピックされてエラーになってしまう、というのがよくある問題で、それを避ける為。この挙動はconfigで変更出来るようになっており、Rails 7.2のデフォルトの設定では上記挙動が有効になっています。無効化したい場合は、config.active_job.enqueue_after_transaction_commit
に:never
を指定すれば良いようになっています。