AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

トランザクション

このガイドでは、MongoDB Go Driver を使ってトランザクションを実行する方法を説明します。トランザクションを使用すると、トランザクションがコミットされるまでデータを変更しない一連の操作を実行できます。トランザクション内のいずれかの操作でエラーが返された場合、ドライバーはトランザクションをキャンセルし、変更が反映される前にすべてのデータ変更を破棄します。

MongoDB では、トランザクションは論理セッション内で実行されます。セッションは、順番に実行されるよう関連付けられた読み取り操作または書き込み操作のグループです。セッションにより、一連の操作に対する因果整合性が有効になる、または ACID transaction 内で操作を実行できるようになります。MongoDBは、トランザクション操作で予期せぬエラーが発生した場合でも、その操作に関わるデータの一貫性が保たれることを保証します。

Go ドライバーを使用する場合、Client インスタンスから Session 型の新しいセッションを作成できます。毎回新しいクライアントをインスタンス化するのではなく、複数のセッションで同じクライアントとトランザクションを使用することを推奨します。

警告

Session は、それを作成した Client(または関連付けられたDatabase または Collection)でのみ使用します。Session と、異なる Client を使用すると、操作エラーが発生します。

警告

Session の実装は、複数の goroutine による同時使用では安全ではありません。

クライアントで StartSession() メソッドを使用してセッションを開始した後、返された Session によって提供されるメソッド セットを使用してセッション状態を変更できます。 次の表では、これらの方法について説明します。

方式
説明

StartTransaction()

このセッションで、指定されたオプションで構成された新しいトランザクションを開始します。セッションで既にトランザクションが実行中の場合はエラーを返します。このメソッドの詳細については、サーバー マニュアルの「startTransaction() ページ」を参照してください。

パラメータ: TransactionOptions
戻り値の型: error

AbortTransaction()

このセッションのアクティブなトランザクションを終了します。セッションにアクティブなトランザクションがない場合、またはトランザクションがコミットされたか、または終了した場合はエラーを返します。このメソッドの詳細については、サーバー マニュアルの abortTransaction() ページを参照してください。

パラメータ: Context
戻り値の型: error

CommitTransaction()

このセッションのアクティブなトランザクションをコミットします。セッションにアクティブなトランザクションがない場合、またはトランザクションが終了した場合はエラーを返します。このメソッドの詳細については、サーバー マニュアルの commitTransaction() ページを参照してください。

CommitTransaction() メソッドは冪等関数であるため、最初のコミットに成功した後は、データを変更せずにトランザクションのコミットを複数回試行できます。トランザクションは成功しますが、UnknownTransactionCommitResult ラベルのエラーが返されます。このエラーを受け取った後に CommitTransaction() メソッドを再実行した場合、繰り返しの試行によってデータは変更されません。


パラメータ: Context
戻り値の型: error

WithTransaction()

このセッションでトランザクションを開始し、 fn コールバックを実行します。

パラメーター: Contextfn func(ctx SessionContext)TransactionOptions
戻り値の型: anyerror

EndSession()

既存のトランザクションを終了し、セッションを閉じます。

パラメータ: Context
戻りの型: なし

Sessionには、セッション プロパティを取得し、可変セッション プロパティを変更するメソッドもあります。 これらのメソッドの詳細については、 API ドキュメントを表示します。

セッションレベルおよびトランザクションレベルでオプションを設定し、ドライバーがトランザクションを実行する方法をカスタマイズできます。以下の手順では、特定の Session 内で実行されるすべてのトランザクションに対するオプションの設定方法を説明します。

  1. TransactionOptions インスタンスを作成します。指定されたセッションで実行されるすべてのトランザクションに対して、書込み保証 (write concern)、読み取り保証 (read concern)、読み込み設定 (read preference) などのオプションを指定できます。

  2. SetDefaultTransactionOptions() メソッドを呼び出し、TransactionOptions インスタンスをパラメータとして渡して、SessionOptions インスタンスを作成します。

    また、SessionOptions インスタンスで因果整合性などの他のセッションオプションを指定することも可能です。

  3. SessionOptions インスタンスを client.StartSession() メソッドに渡します。

次のコードは、セッションとトランザクションのオプションを指定し、これらのオプションを用いてセッションを作成します。

txnOpts := options.Transaction().SetReadConcern(readconcern.Majority())
sessOpts := options.Session().SetDefaultTransactionOptions(txnOpts)
session, err := client.StartSession(sessOpts)
if err != nil {
return err
}

注意

並列操作はサポートされていません

Go ドライバーは、1 つのトランザクション内で並列操作を実行することをサポートしていません。

アプリケーションが MongoDB Server v8.0 以降に接続されている場合、クライアントの一括書き込み機能を使用して、単一のトランザクション内で複数の名前空間に対して書き込み操作を実行できます。詳細については、『一括操作ガイド』のクライアント一括書き込みセクションを参照してください。

このセクションの例では、コレクションに挿入するドキュメントのデータモデルとして、次の Book 構造体を使用します。

type Book struct {
Title string `bson:"title"`
Author string `bson:"author"`
}

次の例は、以下の手順でセッションを作成し、トランザクションを作成し、複数のドキュメント挿入操作をコミットする方法を示しています。

  1. StartSession()メソッドを使用してクライアントからセッションを作成します。

  2. トランザクションを開始するには、 WithTransaction() メソッドを使用します。

  3. 複数のドキュメントを挿入します。WithTransaction() メソッドは挿入を実行し、トランザクションをコミットします。いずれかの操作でエラーが発生した場合、 WithTransaction() がトランザクションのキャンセルを取り扱います。

  4. EndSession() メソッドを使用してトランザクションとセッションを閉じます。

wc := writeconcern.Majority()
txnOptions := options.Transaction().SetWriteConcern(wc)
// Starts a session on the client
session, err := client.StartSession()
if err != nil {
panic(err)
}
// Defers ending the session after the transaction is committed or ended
defer session.EndSession(context.TODO())
// Inserts multiple documents into a collection within a transaction,
// then commits or ends the transaction
result, err := session.WithTransaction(context.TODO(), func(ctx context.Context) (any, error) {
result, err := coll.InsertMany(ctx, []any{
Book{Title: "The Bluest Eye", Author: "Toni Morrison"},
Book{Title: "Sula", Author: "Toni Morrison"},
Book{Title: "Song of Solomon", Author: "Toni Morrison"},
})
return result, err
}, txnOptions)

トランザクションをさらに制御する必要がある場合は、トランザクションを手動で作成、コミット、および終了できます。この例では、次のアクションを実行する方法を示しています。

  1. StartSession()メソッドを使用してクライアントからセッションを作成します。

  2. トランザクションを開始するには、 StartTransaction() メソッドを使用します。

  3. トランザクション内に複数のドキュメントを挿入します。

  4. CommitTransaction()メソッドを使用してトランザクションをコミットします。

  5. EndSession() メソッドを使用してセッションを終了します。

wc := writeconcern.Majority()
txnOptions := options.Transaction().SetWriteConcern(wc)
// Starts a session on the client
session, err := client.StartSession()
if err != nil {
panic(err)
}
// Defers ending the session after the transaction is committed or ended
defer session.EndSession(context.TODO())
err = mongo.WithSession(context.TODO(), session, func(ctx context.Context) error {
if err = session.StartTransaction(txnOptions); err != nil {
return err
}
docs := []any{
Book{Title: "The Year of Magical Thinking", Author: "Joan Didion"},
Book{Title: "Play It As It Lays", Author: "Joan Didion"},
Book{Title: "The White Album", Author: "Joan Didion"},
}
result, err := coll.InsertMany(ctx, docs)
if err != nil {
return err
}
if err = session.CommitTransaction(ctx); err != nil {
return err
}
fmt.Println(result.InsertedIDs)
return nil
})
if err != nil {
if err := session.AbortTransaction(context.TODO()); err != nil {
panic(err)
}
panic(err)
}

挿入操作の詳細については、 ドキュメントの挿入 の基礎ページを参照してください。

Go ドライバーで書込み保証 (write concern) を指定する方法の詳細については、「書込み保証 (write concern)」を参照してください。

Go Driver でセッションとトランザクションを使用する追加の例については、マルチドキュメント ACID トランザクションに関する開発者ブログ記事を参照してください。

このガイドで説明した型やメソッドの詳細については、次の API ドキュメントを参照してください。