【问题标题】:node.js design pattern for creating db connection once用于创建数据库连接一次的 node.js 设计模式
【发布时间】:2011-09-10 15:56:27
【问题描述】:

我正在寻求有关在我的 node.js 应用程序中创建数据库连接的设计模式的帮助。

这似乎很明显:

模块1:

var db;
exports.get_db = function(callback) {

  if (db == null) {
    dblibrary.create(connection_params, function(error, conn) {
      if (error == null) {
        db = conn;
        callback(null, db);
      }
    });
  } else {
    callback(null, db);
  }
};

模块2:

exports.do_something = function () {
  module1.get_db(function (err, conn) {
    if (err == null) {
      // continue using query
    }
  });
};

不得不以使用回调的要求惩罚每个想要获得数据库连接的人似乎很痛苦。

我可以这样做:

模块1:

var db;

dblibrary.create_connection(connection_params, function (err, conn) {

  if (err != null) {
     console.log("can't create connection");
     console.log(err);
     process.exit();
  } else {
     db = conn;
  }
});

exports.get_db = function() {
  return db;
};

这使得获取数据库连接变得简单而快速,但这意味着我们必须在节点启动时“等待”才能建立连接。

哪个设计更好?有没有更好的做事方式?

【问题讨论】:

    标签: javascript database design-patterns node.js


    【解决方案1】:

    mydb.js模块:

    var db
    exports.db = function() {
        if (db === null) {
            db = dblibrary.createClient()
        }
        return db
    }
    

    其他模块:

    var db = require('mydb').db()
    ...
    db.query(...)
    

    这会在启动时创建一次数据库客户端实例。我喜欢这个解决方案,因为创建代码被封装在一个单独的模块中,其他模块可以通过一个 require() 语句访问客户端。

    【讨论】:

    • 如果 dblibrary 只创建异步数据库会怎样?理论上,mydb.js 还没有完成创建,但主应用程序可能已经开始执行,不是吗?
    • @MarcWan 是的,这不适用于异步客户端创建(实际上这根本行不通,不仅仅是理论上)。我正在使用同步的node_redis。但是,这段代码只在启动时运行一次。
    • 您是否曾经担心您的应用只共享一个数据库连接?如果该连接在长时间运行的查询中被占用,您的应用程序的其余部分不会受到影响吗?
    • 实际上当你用var定义一个变量而不赋值时,你会得到一个undefined而不是null,所以在这段代码中你总是会得到undefined
    • 恶意点击让我对此投了反对票,但我无法删除:/
    【解决方案2】:

    我见过的最佳答案是:

    在 start.js 中:

        function init_done() {
    
          app.listen(8080);
    
        }
    
    
    init_databases(init_done);
    

    在databases.js中:

    init_databases(init_done_cb) {
    
      db.create_async(/* connect data */ , function (err, res) {
    
        if (err == null) init_done_cb();
    
      });
    }
    

    这样您就可以在没有尴尬/危险的等待期的情况下进行数据库服务器的异步启动。

    【讨论】:

    • 以及何时/如何断开连接?
    • 当你的命令行任务也使用模型并且需要数据库连接时,不处理这种情况。连接应在第一次需要时创建,并一直保持到服务器关闭。
    • 我不知道异步数据库的优势,@marcWan 你必须使连接变量全局然后只有其他模块可以轻松使用(不再需要)
    【解决方案3】:

    我写connect-once 就是为了解决这类问题。该模块实现了两个主要目标:

    1. 应在请求到达之前初始化连接
    2. 连接应该初始化一次,即使有多个请求同时进来

    您可以查看express-mongo-dbexpress-mongoose-db 作为使用示例。

    【讨论】:

    • 我不明白这有什么帮助。示例代码仍然有回调。
    • @ian-warburton 技巧是将传入的客户端置于等待状态并创建一次连接。如果客户不断出现并且已经请求连接 - 那么什么也不做。回调在这里不是问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 2018-12-16
    • 1970-01-01
    • 2013-07-18
    相关资源
    最近更新 更多