AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Docs Menu

トランザクションとセッション

このガイドでは、 MongoDB PHPライブラリを使用してトランザクションを実行する方法を学習できます。 トランザクションを使用すると、トランザクション全体がコミットされた場合にのみ、データを変更する一連の操作を実行できます。 トランザクション内のいずれかの操作が成功しない場合、ライブラリはトランザクションを停止し、変更が反映される前にすべてのデータ変更を破棄します。 この特徴はアトミック性と 呼ばれます。

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

MongoDB PHPライブラリを使用すると、 MongoDB\Clientインスタンスから新しいセッションを作成できます。 その後、結果のMongoDB\Driver\Sessionインスタンスを使用してトランザクションを実行できます。

警告

Sessionは、それを作成したClientで実行されている操作でのみ使用します。 Sessionと別のClientを使用すると、操作エラーが発生します。

MongoDB は特定のクライアントセッションで因果整合性を有効にします。因果整合性モデルは、分散システム内でセッション内の操作が因果順序で実行されることを保証します。クライアントは、因果関係、または操作間の依存関係と整合性のある結果を観察します。例、ある操作が別の操作の結果に論理的に依存する一連の操作を実行すると、後続のすべての読み取りは 依存関係を反映します。

因果整合性を保証するには、クライアントセッションが次の要件を満たす必要があります。

  • セッションを開始するとき、ドライバーは 因果整合性 オプションを有効にする必要があります。このオプションはデフォルトで有効になっています。

  • 操作は 1 つのスレッド上の 1 つのセッションで実行する必要があります。それ以外の場合、セッションまたはスレッドは optime とクラスター時間の値を相互に通信する必要があります。 これらの値を通信する 2 つのセッションの例については、 MongoDB Serverマニュアルの 因果整合性の例 を参照してください。

  • majority の読み取り保証 (read concern)を使用する必要があります。

  • majority の書込み保証 (write concern)を使用する必要があります。これは、デフォルトの書込み保証 (write concern)の値です。

次の表では、因果整合性のあるセッションが提供する保証について説明しています。

保証
説明

書込み操作の結果を読み取る

読み取り操作は、前の書込み操作の結果を反映します。

単調な読み取り

読み取り操作では、前の 読み取り操作よりも前のデータ状態を反映した結果は返されません。

単調書込み

書込み操作が他の書込み操作に優先する必要がある場合、サーバーはこの書込み操作を最初に実行します。

例、MongoDB\Collection::insertOne() を呼び出してドキュメントを挿入し、MongoDB\Collection::updateOne() を呼び出して挿入されたドキュメント を変更すると、サーバーは最初に挿入操作を実行します。

書込み操作の前に読み取り操作をする

書込み操作が他の読み取り操作の後に続く必要がある場合、サーバーは最初に読み取り操作を実行します。

例、MongoDB\Collection::findOne() を呼び出してドキュメントを取得し、MongoDB\Collection::deleteOne() を呼び出して取得されたドキュメントを削除すると、サーバーは最初に検索操作を実行します。

Tip

このセクションで述べられた概念の詳細については、次のMongoDB Serverマニュアル エントリを参照してください。

このセクションでは、 MongoDB PHPライブラリが提供するトランザクション API について学習できます。 トランザクションを開始する前に、 ClientインスタンスでMongoDB\Client::startSession()メソッドを使用してSessionを作成する必要があります。 その後、次のいずれかの API を使用してトランザクションを実行できます。

MongoDB PHPライブラリは、トランザクションのライフサイクルを管理するためのConvenient Transaction APIを提供します。 このAPIを実装するには、 MongoDB\with_transaction()関数を使用してトランザクション内でカスタムコールバックを実行します。 with_transaction()関数は、次のタスクを実行します。

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

  • 操作が を返した場合など、トランザクションを終了するか再試行することでエラーを処理します TransientTransactionError

  • トランザクションをコミットする

このガイドの「トランザクションの例」セクションでは、このAPIを使用してトランザクションを実行する方法を示します。

あるいは、 Sessionクラスが提供するメソッドを使用して、トランザクション ライフサイクルをより制御できます。 次の表では、これらの方法について説明します。

方式
説明

startTransaction()

このセッションで新しいトランザクションを開始します。セッションはトランザクション内の各操作に渡される必要があります。そうしないと、操作はトランザクションの外部で実行されます。オプション

パラメータを渡すことでトランザクション オプションを設定できます。

commitTransaction()

このセッションのアクティブなトランザクションをコミットします。このメソッドは、セッションにアクティブなトランザクションがない場合、トランザクションが以前に終了された場合、または書込み競合 (write conflict)が発生している場合はエラーを返します。

abortTransaction()

このセッションのアクティブなトランザクションを終了します。 このメソッドは、セッションにアクティブなトランザクションがない場合、またはトランザクションがコミットされたか、または終了した場合は、エラーを返します。

この例では、金融トランザクションのためにbankデータベースのコレクション内のデータを変更するコールバック関数を定義します。 このコードは、次のアクションを実行します。

  • ターゲット コレクションにアクセスするためのCollectionインスタンスを作成します。

  • アカウント間で転送されるアカウント番号と金額を指定します。

  • コールバック関数を定義します。この関数は、 Sessionインスタンスをパラメータとして受け取ります。

  • 送金を反映するようにカスタマーの残高を更新します。

  • トランザクションの受信をタイムスタンプとともに記録します。

  • トランザクションが正常にコミットされた場合は、メッセージを出力します。

$receipts = $client->bank->receipts;
$checking = $client->bank->checking_accounts;
$saving = $client->bank->saving_accounts;
$accountId = '5678';
$transferAmount = 1000.0;
$callback = function (MongoDB\Driver\Session $session) use (
$checking,
$saving,
$receipts,
$accountId,
$transferAmount,
): void {
$checking->updateOne(
['account_id' => $accountId],
['$inc' => ['balance' => -$transferAmount]],
['session' => $session],
);
$saving->updateOne(
['account_id' => $accountId],
['$inc' => ['balance' => $transferAmount]],
['session' => $session],
);
$summary = sprintf('SAVINGS +%1$u CHECKING -%1$u', $transferAmount);
$receipts->insertOne(
[
'account_id' => $accountId,
'summary' => $summary,
'timestamp' => new MongoDB\BSON\UTCDateTime(),
],
['session' => $session],
);
echo 'Successfully performed transaction!', PHP_EOL;
echo 'Summary: ', $summary, PHP_EOL;
};

次に、次のコードを実行してトランザクションを実行します。 このコードは、次のアクションを完了します。

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

  2. セッションとコールバックをパラメータとして渡して、トランザクションを管理するためにwith_transaction()関数を呼び出します。

$session = $client->startSession();
try {
MongoDB\with_transaction($session, $callback);
} catch (MongoDB\Driver\Exception\RuntimeException $e) {
echo 'Caught exception: ', $e->getMessage(), PHP_EOL;
}
Successfully performed transaction!
Summary: SAVINGS +1000 CHECKING -1000

注意

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

PHPライブラリは、単一のトランザクション内での並列操作の実行中をサポートしていません。

PHPライブラリ v2.1 以降とMongoDB Server v8.0 以降を使用している場合は、 メソッドを使用して、1MongoDB\Client::bulkWrite() つのトランザクション内で複数の名前空間に対して書込み操作を実行できます。詳細については、一括書込み (write) 操作 を参照してください。

このガイドで言及されている概念の詳細については、 MongoDB Serverマニュアルの次のページ を参照してください。

ACID compliance の詳細については、 「 データベース管理システムの ACID プロパティとは 」を参照してください。 MongoDB Webサイトの記事。

挿入操作の詳細については、ドキュメントの挿入ガイドを参照してください。

このガイドで言及されているメソッドとタイプの詳細については、次のAPIドキュメントを参照してください。

Sessionクラスとメソッドの詳細については、次のPHP拡張APIドキュメントを参照してください。