84

MongoDB を使用した非常に多くの入門的な例では、次のようなコードが表示されます。

var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://localhost:port/adatabase", function(err, db)
{
    /* Some operation... CRUD, etc. */
    db.close();
});

MongoDB が他のデータベース システムと同様であり、通常openclose操作は時間的にコストがかかります。

MongoClient.connect("...それで、私の質問は次のとおりです。一度だけ実行し、返された値をモジュールグローバルに割り当て、dbモジュール内のさまざまな関数にさまざまなデータベース関連の作業(コレクションへのドキュメントの挿入、ドキュメントの更新など)を実行させても大丈夫ですか. ) それらがアプリケーションの他の部分によって呼び出されたとき (したがって、そのdb値を再利用するとき)、そしてアプリケーションが完了したときにのみ、close.

つまり、データベース関連の操作を実行する必要があるたびに実行する必要はopenありcloseません。dbそして、最初の で返されたオブジェクトを再利用し続けますが、データベース関連のすべての作業が実際に完了したときにopen\connect、最後に で破棄するだけです。close

明らかに、すべての I/O は非同期であるcloseため、close. これで問題ないように思えますが、MongoDB を初めて使用するため、何か不足している場合に備えて再確認したかったのです。ありがとう!

4

3 に答える 3

67

はい、それは問題なく、典型的な動作です。アプリを起動し、データベースに接続し、データベースに対して長時間操作を行い、接続が予期せず切断された場合は再接続し、接続を閉じないでください (プロセスが停止したときに発生する自動終了に頼るだけです)。 .

于 2013-09-06T06:21:58.960 に答える
5

現在受け入れられている回答は、操作を実行するために同じデータベース接続を開いたままにしておくことができるという点で正しいですが、閉じた場合に接続を再試行する方法に関する詳細が欠落しています。以下に、自動的に再接続する 2 つの方法を示します。これは TypeScript ですが、必要に応じて通常の Node.js に簡単に変換できます。

方法 1: MongoClient オプション

MongoDB が再接続できるようにする最も簡単な方法は、 に渡すときに を で定義するreconnectTriesことoptionsですMongoClient。CRUD 操作がタイムアウトになると、渡されたパラメーターを使用しMongoClientて再試行 (再接続) する方法が決定されます。オプションをNumber.MAX_VALUE本質的に設定すると、操作を完了することができるまで永遠に再試行するようになります。どのエラーが再試行されるかを確認したい場合は、ドライバーのソース コードをチェックアウトできます。

class MongoDB {
    private db: Db;

    constructor() {
        this.connectToMongoDB();
    }

    async connectToMongoDB() {
        const options: MongoClientOptions = {
            reconnectInterval: 1000,
            reconnectTries: Number.MAX_VALUE
        };

        try {
            const client = new MongoClient('uri-goes-here', options);
            await client.connect();
            this.db = client.db('dbname');
        } catch (err) {
            console.error(err, 'MongoDB connection failed.');
        }
    }

    async insert(doc: any) {
        if (this.db) {
            try {
                await this.db.collection('collection').insertOne(doc);
            } catch (err) {
                console.error(err, 'Something went wrong.');
            }
        }
    }
}

方法 2: try-catch リトライ

再接続の試行についてより詳細なサポートが必要な場合は、while ループで try-catch を使用できます。たとえば、再接続する必要があるときにエラーをログに記録したり、エラーの種類に基づいてさまざまなことをしたりすることができます。これにより、ドライバーに含まれている標準的な条件だけでなく、より多くの条件に応じて再試行することもできます。メソッドは次のinsertように変更できます。

async insert(doc: any) {
    if (this.db) {
        let isInserted = false;

        while (isInserted === false) {
            try {
                await this.db.collection('collection').insertOne(doc);
                isInserted = true;
            } catch (err) {
                // Add custom error handling if desired
                console.error(err, 'Attempting to retry insert.');

                try {
                    await this.connectToMongoDB();
                } catch {
                    // Do something if this fails as well
                }
            }
        }
    }
}
于 2020-03-12T21:19:25.327 に答える