保持打开MongoDB数据库连接

时间:2013-09-06 05:58:28

标签: node.js mongodb

在使用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

换句话说,openclose只执行一次 - 不是每次都需要去做一些与数据库相关的操作。并且您继续重复使用在初始db期间返回的open\connect对象,仅在最后使用close处理它,当您实际完成所有操作时与数据库相关的工作。

显然,由于所有I / O都是异步的,因此在close之前,您需要确保在发出close之前完成最后一次数据库操作。看起来这样应该没关系,但我想仔细检查,以防万一我错过了一些东西,因为我是MongoDB的新手。谢谢!

3 个答案:

答案 0 :(得分:46)

是的,这是很好的典型行为。启动你的应用程序,连接到db,长时间对数据库执行操作,如果连接意外死亡,可能重新连接,然后永远不要关闭连接(只需依赖于进程终止时自动关闭)

答案 1 :(得分:3)

mongodb版本^ 3.1.8

将连接初始化为承诺:

const MongoClient = require('mongodb').MongoClient
const uri = 'mongodb://...'
const client = new MongoClient(uri)
const connection = client.connect() // initialized connection

然后在希望对数据库执行任何操作时调用连接:

    // if I want to insert into the database...
    const connect = connection
    connect.then(() => {
        const doc = { id: 3 }
        const db = client.db('database_name')
        const coll = db.collection('collection_name')
        coll.insertOne(doc, (err, result) => {
            if(err) throw err
        })
    })

答案 2 :(得分:1)

当前接受的答案是正确的,因为您可以保持相同的数据库连接打开以执行操作,但是,它缺少有关在关闭时如何重试连接的详细信息。以下是两种自动重新连接的方法。它在TypeScript中,但是如果需要,可以轻松地转换为普通的Node.js。

方法1:MongoClient选项

允许MongoDB重新连接的最简单方法是在将reconnectTries传递到options时在MongoClient中定义一个MongoClient。每当CRUD操作超时时,它将使用传递到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.'); } } } } 实际上会使它重试,直到它可以完成操作为止。如果您想查看重试哪些错误,可以check out the driver source code

insert

方法2:尝试捕获重试

如果您想在尝试重新连接方面获得更详尽的支持,则可以将try-catch与while循环一起使用。例如,您可能需要在必须重新连接时记录错误,或者根据错误的类型执行其他操作。除了驱动程序随附的标准条件外,这还使您可以根据更多条件重试。 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 } } } } } 方法可以更改为以下内容:

{{1}}