再試行可能な書き込み
再試行可能な書き込みを使用すると、MongoDB ドライバーは、ネットワーク エラーが発生した場合、あるいはレプリカセットかシャーディングされたクラスターで正常なプライマリが見つからない場合に、特定の書き込み操作を 1 回自動的に再試行できます。
前提条件
再試行可能な書き込みには、次の要件があります。
- サポートされている配置トポロジー
- 再試行可能な書き込みには、レプリカセットまたはシャーディングされたクラスターが必要で、スタンドアロンインスタンスはサポートされません。
- サポートされているストレージエンジン
- 再試行可能な書き込みには、WiredTiger ストレージエンジンやメモリ内ストレージエンジンなどのドキュメントレベルのロック機能をサポートするストレージエンジンが必要です。
- 3.6+ MongoDB ドライバー
クライアントには、MongoDB 3.6 以降に更新された MongoDB ドライバーが必要です。
Java 3.6+
Python 3.6+
C 1.9+
Go 1.8+
C# 2.5+
Node 3.0+
Ruby 2.5+
Rust 2.1+
Swift 1.2+
Perl 2.0+
PHPC 1.4+
Scala 2.2+
C++ 3.6.6+
- MongoDB バージョン
- クラスター内のすべてのノードの MongoDB バージョンは
3.6
以上で、クラスター内の各ノードのfeatureCompatibilityVersion
は3.6
以上である必要があります。featureCompatibilityVersion
フラグの詳細については、setFeatureCompatibilityVersion
を参照してください。 - 謝辞の書き込み
0
の書込み保証 (write concern) で発行された書き込み操作は、再試行できません。
再試行可能な書き込みとマルチドキュメントトランザクション
トランザクションのコミット操作と中止操作は、再試行可能な書き込み操作です。コミット操作または中止操作でエラーが発生した場合、MongoDB ドライバーは、retryWrites
が false
に設定されているかどうかに関係なく、操作を 1 回再試行します。
トランザクション内の書き込み操作は、retryWrites
の値に関係なく、個別に再試行することはできません。
トランザクションの詳細については、「トランザクション」を参照してください。
再試行可能な書き込みの有効化
- MongoDB ドライバー
- MongoDB 4.2以上と互換性のあるドライバーでは、 の再試行可能な書込みがデフォルトで有効になります。 それ以前のドライバーでは
retryWrites=true
オプションが必要です。 MongoDB 4と互換性のあるドライバーを使用するアプリケーションでは、retryWrites=true
オプションを省略できます。 2以上再試行可能な書き込みを無効にするには、MongoDB 4.2 以降と互換性のあるドライバーを使用するアプリケーションの場合、接続文字列にretryWrites=false
が含まれていなければなりません。 mongosh
再試行可能な書込みは、
mongosh
ではデフォルトで有効になっています。 再試行可能な書込みを無効にするには、--retryWrites=false
コマンドライン オプションを使用します。mongosh --retryWrites=false
再試行可能な書き込み操作
次の書き込み操作は、確認済みの書込み保証 (write concern) とともに発行された場合に再試行可能です。たとえば、書込み保証 (write concern) は {w: 0}
にできません。
注意
トランザクション内の書き込み操作は個別に再試行できません。
メソッド | 説明 |
---|---|
挿入操作 | |
単一ドキュメントのアップデート操作 | |
単一ドキュメントの削除操作 | |
findAndModify の操作です。 すべてのfindAndModify 操作は 1 つのドキュメント操作です。 | |
単一ドキュメントの書き込み操作だけで構成される一括書き込み操作。再試行可能な一括操作には、指定された書き込み操作を自由に組み合わせることができますが、 updateMany などの複数のドキュメントでの書き込み操作を含めることはできません。 | |
単一ドキュメントの書き込み操作だけで構成される一括書き込み操作。再試行可能な一括操作には、指定された書き込み操作を自由に組み合わせることができますが、 multi オプションに true を指定する update などの複数ドキュメントでの書き込み操作を含めることはできません。 |
動作
永続的なネットワークエラー
MongoDB の再試行可能な書き込みでは、再試行は 1 回だけです。これは、一時的なネットワークエラーやレプリカセットの選挙には役立ちますが、永続的なネットワークエラーには対応できません。
フェイルオーバー期間
ドライバーが宛先レプリカセットまたはシャーディングされたクラスター シャード内に正常なプライマリを見つけられない場合、ドライバーは再試行する前に新しいプライマリを決定するために serverSelectionTimeoutMS
ミリ秒待機します。再試行可能な書き込みでは、フェイルオーバー期間が serverSelectionTimeoutMS
を超えるインスタンスには対応しません。
警告
書き込み操作を発行した後、クライアントアプリケーションが localLogicalSessionTimeoutMinutes
を超えて一時的に応答しなくなった場合、クライアントアプリケーションが応答し始めたときに(再起動せずに)、書き込み操作が再試行され、再度適用される可能性があります。
診断
serverStatus
コマンドとそのmongosh
shellヘルパーdb.serverStatus()
には、 transactions
セクションに再試行可能な書込みに関する統計が含まれています。
local
データベースに対する再試行可能な書き込み
公式の MongoDB ドライバーでは、デフォルトで再試行可能な書込みが有効になっています。 再試行可能な書込みが明示的に無効になってい ない限りlocal
、 データベース に書込むアプリケーションでは書込みエラーが発生します。
再試行可能な書き込みを無効にするには、MongoDB の接続文字列に retryWrites=false
を指定します。
Error Handling
MongoDB 6.1 以降では、再試行可能な書き込みの 1 回目と 2 回目の試行の両方が失敗し、書き込みが 1 つも実行されない場合、MongoDB はNoWritesPerformed
ラベルの付いたエラーを返します。
NoWritesPerformed
ラベルは、insertMany()
のようなバッチ操作の結果とを区別します。insertMany
操作では、次のいずれかの結果が発生する可能性があります。
結果 | MongoDB 出力 |
---|---|
ドキュメントは挿入されません。 | NoWritesPerformed ラベルの付いたエラーが返されました。 |
部分的な作業が完了しました。(少なくとも 1 つのドキュメントが挿入されていますが、すべてではありません。) | NoWritesPerformed ラベルの付いていないエラーが返されました。 |
すべてのドキュメントが挿入されます。 | 成功が返されました。 |
アプリケーションは NoWritesPerformed
ラベルを使用して、ドキュメントが挿入されていないことを明確に判断できます。このエラー報告により、アプリケーションは再試行可能な書き込みを処理する場合にデータベースの正確な状態を維持できます。
前のバージョンの MongoDB では、再試行可能な書き込みの 1 回目と 2 回目の両方が失敗するとエラーが返されました。ただし、書き込みが実行されなかったことを示す区別はありません。