mongodb使用find查询返回的游标,是否可以遍历出查询执行后(记录比较多查询时间比较长,此时查询还未执行完)数据表新增的记录。
例如:
线程A在时间点t1使用find查询数据表user返回游标,遍历数据记录。
线程B在时间点t2使用insert向数据表user插入记录。
线程B在时间点t3执行完成。
线程A在时间点t4执行完成。
时间:t1 < t2 < t3 < t4
问:线程A是否可以查询到线程B新增的记录?
PHP中文网2017-04-24 16:02:18
これはとても良い質問です。簡単に言うと、MongoDB には複数のドキュメント (将来挿入される可能性のあるドキュメントも含む) が含まれるため、結果に新しいドキュメントが含まれるかどうかは保証されません。従来のデータベースでは、新しく挿入された値を読み取ることができます。これを満たせる分離レベルは、最も高いシリアル化可能 (シリアル化可能) レベルです。つまり、この例では、2 つの操作で 1 つの読み取りが行われます。と一つの書き込みが次々と行われているようです。ロック機構の実装コストも非常に高く、パフォーマンスも比較的劣ります。この論文を参照してください。 MongoDB の話に戻ると、MongoDB はドキュメントを単位として使用し、ドキュメントレベルの分離を保証できますが、高いパフォーマンスと引き換えに、複数のドキュメント間の操作の分離 (独立性) は保証されず、トランザクションもサポートしていません。
@huandu が正しいです。テストするときは、find().batchSize(2)
を使用して各バッチで 2 つのドキュメントを読み取ると、新しく追加されたドキュメントを読み取ることができることがわかります。シェルのデフォルトのbatchSizeは20ですが、これを確認するのは簡単ではないかもしれません。歴史的な理由から、batchSize(1) はlimit() と同じなので使用しないでください。
曾经蜡笔没有小新2017-04-24 16:02:18
必ずしもそうとは限りません。
mongodb カーソルには分離がなく、更新されたデータを返す場合があります。
しかし、実際に試してみると、いくら挿入してもカーソルが新しく挿入したデータを返すことができないことが分かりました。これは mongodb の実装の詳細である可能性があります。あるいは、カーソルが特定の特殊な状況下でのみ新しく挿入されたデータにアクセスできるということも考えられます。つまり、ドキュメントのサポートがないため、この動作に依存すべきではありません。