当前位置:  开发笔记 > 编程语言 > 正文

何时关闭Nodejs中的MongoDB数据库连接

如何解决《何时关闭Nodejs中的MongoDB数据库连接》经验,为你挑选了3个好方法。

通过Node MongoDB本机驱动程序使用Nodejs和MongoDB.需要检索一些文档并进行修改,然后将它们保存回来.这是一个例子:

db.open(function (err, db) {
  db.collection('foo', function (err, collection) {
    var cursor = collection.find({});
    cursor.each(function (err, doc) {
      if (doc != null) {
        doc.newkey = 'foo'; // Make some changes
        db.save(doc); // Update the document
      } else {
        db.close(); // Closing the connection
      }
    });
  });
});

具有异步性质,如果更新文档的过程需要更长时间,那么当游标到达文档末尾时,数据库连接将关闭.并非所有更新都保存到数据库中.

如果db.close()省略,则所有文档都已正确更新,但应用程序挂起,永不退出.

我看到一篇帖子暗示使用计数器跟踪更新次数,当回落到零时,然后关闭数据库.但我在这里做错了吗?处理这种情况的最佳方法是什么?是否db.close()必须用来释放资源?或者是否需要打开新的数据库连接?



1> mpobrien..:

这是一个基于计数方法的潜在解决方案(我没有测试它,也没有错误捕获,但它应该传达这个想法).

基本策略是:获取需要更新的记录数,异步保存每条记录以及成功回调,如果计数达到0(上次更新完成时),将减少计数并关闭数据库.通过使用,{safe:true}我们可以确保每次更新都成功.

mongo服务器将为每个连接使用一个线程,因此最好是a)关闭未使用的连接,或者b)池/重用它们.

db.open(function (err, db) {
  db.collection('foo', function (err, collection) {
    var cursor = collection.find({});
    cursor.count(function(err,count)){
      var savesPending = count;

      if(count == 0){
        db.close();
        return;
      }

      var saveFinished = function(){
        savesPending--;
        if(savesPending == 0){
          db.close();
        }
      }

      cursor.each(function (err, doc) {
        if (doc != null) {
          doc.newkey = 'foo'; // Make some changes
          db.save(doc, {safe:true}, saveFinished);
        }
      });
    })
  });
});


@realguess,还有并发工具库,可以帮助你做这些事情,所以你不必管理细节.查看async.js,例如https://github.com/caolan/async

2> pkopac..:

最好使用池连接,然后在应用程序生命周期结束时在清理函数中调用db.close():

process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);

见http://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html

有点旧线程,但无论如何.



3> cl yu..:

我发现使用计数器可能适用于简单的场景,但是在复杂的情况下可能很难。这是我通过在数据库连接空闲时关闭数据库连接来提出的解决方案:

var dbQueryCounter = 0;
var maxDbIdleTime = 5000; //maximum db idle time

var closeIdleDb = function(connection){
  var previousCounter = 0;
  var checker = setInterval(function(){
    if (previousCounter == dbQueryCounter && dbQueryCounter != 0) {
        connection.close();
        clearInterval(closeIdleDb);
    } else {
        previousCounter = dbQueryCounter;
    }
  }, maxDbIdleTime);
};

MongoClient.connect("mongodb://127.0.0.1:27017/testdb", function(err, connection)(
  if (err) throw err;
  connection.collection("mycollection").find({'a':{'$gt':1}}).toArray(function(err, docs) {
    dbQueryCounter ++;
  });   
  //do any db query, and increase the dbQueryCounter
  closeIdleDb(connection);
));

这可以是任何数据库连接的通用解决方案。可以将maxDbIdleTime设置为与数据库查询超时相同的值或更长。

这不是很优雅,但是我想不出更好的方法来做到这一点。我使用NodeJs运行一个查询MongoDb和Mysql的脚本,如果数据库连接未正确关闭,该脚本将永远挂在那里。

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有