Docs Menu
Docs Home
/ / /
Mongoid
/

トランザクション

項目一覧

  • トランザクションの使用
  • 高レベル API
  • 下位レベル API

MongoDB サーバーのバージョン4.0では、 マルチドキュメントトランザクションが導入されています。 (単一のドキュメント内の複数のフィールドの更新は、MongoDB のすべてのバージョンでアトミックです)。 トランザクションには非スタンドアロンの MongoDB トポロジーと Ruby ドライバー バージョン2.6以上が必要です。 高レベルのトランザクション API には Mongoid バージョン9.0以上が必要で、下位レベルの API には Mongoid バージョン6が必要です。 4以上

トランザクションは、Mongoid ドキュメント クラスのインスタンス、Mongoid ドキュメント クラス、またはMongoidモジュールで transactionメソッドを呼び出すことで開始できます。

Band.transaction do
Band.create(title: 'Led Zeppelin')
end
band = Band.create(title: 'Deep Purple')
band.transaction do
band.active = false
band.save!
end
Mongoid.transaction do
band.destroy
end

transactionメソッドが呼び出されると、Mongoid は次の処理を実行します。

  • は、 transactionメソッド呼び出しの受信者が使用するクライアント上でセッションを作成します。

  • セッションでトランザクションを開始する

  • 指定されたブロックを実行し、

  • ブロック内で例外が発生しない場合はトランザクションをコミットします。

    • トランザクション内で変更されたすべてのオブジェクトに対してafter_commitコールバックを呼び出す

  • ブロックで例外が発生した場合はトランザクションを中止します。

    • トランザクション内で変更されたすべてのオブジェクトに対してafter_rollbackコールバックを呼び出す

  • セッションを閉じます

注意

トランザクションは特定のクライアントに関連付けられているため、同じクライアントでの _only_ 操作はトランザクションの範囲内になります。 したがって、 transactionメソッド ブロック内では同じクライアントを使用するオブジェクトのみを使用することをお勧めします。

class Author
include Mongoid::Document
store_in client: :encrypted_client
end
class User
include Mongoid::Document
store_in client: :encrypted_client
end
class Article
include Mongoid::Document
# This class uses the :default client
end
# Transaction is started on the :encrypted_client
Author.transaction do
# This operation uses the same client, so it is in the transaction
Author.create!
# This operation also uses the same client, so it is in the transaction
User.create!
# This operation uses a different client, so it is NOT in the transaction
Article.create!
end

注意

Mongoidモジュールでtransactionメソッドが呼び出されると、 :defaultクライアントを使用してトランザクションが作成されます。

transactionメソッド ブロック内で発生した例外はトランザクションを中止します。 通常、発生した例外は に渡されます。ただし、 Mongoid::Errors::Rollbackは除きます。 例外を渡しずにトランザクションを明示的に中止する場合は、このエラーが発生します。

Transaction API には、 after_commitafter_rollbackの 2 つの新しいコールバックが導入されています。

after_commit コールバックは、作成、保存、または破棄されたオブジェクトに対してトリガーされます。

  • トランザクション内でオブジェクトが変更された場合は、トランザクションがコミットされた後。

  • オブジェクトがトランザクション外で変更された場合に、オブジェクトが保持された後。

注意

いずれの場合も、 after_commitコールバックは、他のすべてのコールバックが正常に実行された後にのみトリガーされます。 したがって、トランザクションなしでオブジェクトが変更されている場合、オブジェクトは永続化されていたが、 after_commitコールバックはトリガーされなかった可能性があります(たとえば、 after_saveコールバックで例外が発生した)。

after_rollback コールバックは、トランザクションが中止された場合にトランザクション内で作成、保存、または破棄されたオブジェクトに対してトリガーされます。 after_rollbackはトランザクションなしではトリガーされません。

トランザクションを開始するには、アプリケーションにセッションが必要です。

トランザクションはセッションでstart_transactionメソッドを呼び出すことで開始できます。このトランザクションは、モデル クラスまたは インスタンスのいずれかでwith_sessionメソッドを呼び出すことで取得できます。

class Person
include Mongoid::Document
end
Person.with_session do |session|
session.start_transaction
end
person = Person.new
person.with_session do |session|
session.start_transaction
end

トランザクションを開始するときに、読み取り保証、書込み保証、および読み込み設定(read preference)を指定することもできます。

Person.with_session do |session|
session.start_transaction(
read_concern: {level: :majority},
write_concern: {w: 3},
read: {mode: :primary})
end

トランザクションはコミットまたは中止される可能性があります。 また、セッション インスタンスでは、それに対応するメソッドもcommit_transactionabort_transactionです。

Person.with_session do |session|
session.commit_transaction
end
Person.with_session do |session|
session.abort_transaction
end

オープン トランザクションでセッションが終了すると、そのトランザクションは 中止されます 。

トランザクションのコミットは失敗した場合に再試行できます 。 以下は、そのための Ruby コードです。

begin
session.commit_transaction
rescue Mongo::Error => e
if e.label?(Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)
retry
else
raise
end
end

トランザクション内で操作を実行するには、セッションが開始されたのと同じクライアントを使用する必要があることに注意してください。 デフォルトでは、すべての操作はデフォルトのクライアントで実行されます。

class Person
include Mongoid::Document
end
class Post
include Mongoid::Document
end
Person.with_session do |s|
s.start_transaction
Person.create!
Person.create!
Post.create!
s.commit_transaction
end

別のクライアントを明示的に使用するには、 withメソッドを使用します。

Post.with(client: :other) do
Person.with(client: :other) do
Person.with_session do |s|
s.start_transaction
Person.create!
Person.create!
Post.create!
s.commit_transaction
end
end
end

戻る

セッション