はじめに
本稿は、分散トランザクションの内部メカニズムについて概観を与えることを目的としています。
本記事の関連情報として以下をご参照ください。
Couchbase Java SDK解説:分散トランザクション〜エラー処理を理解する
Couchbase Java SDK解説:分散トランザクションプログラミング入門
アクティブトランザクションレコード(ATR)
トランザクションとして実行されるアプリケーションロジックを含むラムダブロックは、トランザクションライブラリによって複数回実行される可能性があります。この場合の各実行を、ここでは「試行」と呼びます。
各試行は、ドキュメントのメタデータにエントリーを追加します。このメタデータエントリーは、アクティブ・トランザクション・レコード(ATR)と呼ばれます。エントリーの名前は、「_txn:atr-
」から、始まります。 ATRは、Couchbase SDKによって、自動的に作成・運用されます。これらのメタデータエントリーは、可視的ですが、外部から変更してはなりません。
このATRエントリーには、その試行がコミットされたかどうかについての情報が格納されます。このエントリーはトランザクションの信頼できる唯一の情報源として機能します。これは、後で見るように、「アトミックコミット」を実現するために別のトランザクションアクターからの読み取り時に利用されます。
ドキュメント変更(ミューテーション)のステージング
Couchbase SDKでは、トランザクション内でドキュメントを変更しても、実際のドキュメントは直接変更されません。その代わりに、トランザクション後のバージョンのドキュメントの内容がそのドキュメントの拡張属性(XATTR)として保存されます。このような機構は、「ステージング」と呼ばれます。
このような段階的なドキュメントの変更機構は、ドキュメントを変更しようとする他のトランザクションに対するロックとして機能し、書き込みの競合を防ぎます。
コミット
ラムダが正常に実行されて結果が返された場合にのみ、その試行はコミットされます。これにより、試行エントリーが更新されます。これは、トランザクションアクターがXATTRからドキュメントのトランザクション後バージョンを使用するかどうかに関するシグナルとして使用されます。つまり、ATRエントリの更新は、事実上、トランザクションの「アトミックコミット」スイッチとして機能します。
トランザクションアクター
トランザクションアクターは、ATRエントリがコミット済みに変更されるとすぐに、トランザクション後のバージョンのドキュメントの読み取りを開始します。
非トランザクションアクター
このアトミックコミットポイントに達した後、個々のドキュメントの実際の内容が更新されます(これを「アンステージング」と呼びます)。これにより、非トランザクションアクター(標準のKey-Value読み取りとN1QLステートメントを含む)に結果整合性のある結果が提供されます。
クリーンアップ
失敗したトランザクションが、他のトランザクションを無期限にブロックしないようにするため、Couchbase SDKは、「クリーンアップ」と呼ばれるメカニズムを提供します。
トランザクションは、失敗が発生したときに、まず自分自身でクリーンアップしようとします。
非同期クリーンアップ
アプリケーションのクラッシュなどの原因で、そのトランザクション自身によってクリーンアップされなかった、「ロスト」トランザクションが作成される状況があります。
そのためクリーンアップメカニズムには、Transactions
オブジェクトの作成時に開始される非同期クリーンアップのためのバックグラウンドプロセスが含まれます。このプロセスは、任意のアプリケーションによって作成された、すべてのバケットにおける期限切れのトランザクションをスキャンします。つまり、アプリケーションは、別のアプリケーションによって作成されたトランザクションをクリーンアップする場合があります。
アプリケーションが実行されていない期間、非同期クリーンアップは実行されていないことに注意する必要があります。これは、単体テストの実行に関係してきます。このことが問題となる場合、非同期クリーンアップが常に実行されていることを確実にするために、Transactions
オブジェクトをオープンするだけの単純なアプリケーションを実行しておくことが考えられます。