【问题标题】:Calling node-oracledb's createPool Method调用 node-oracledb 的 createPool 方法
【发布时间】:2019-04-22 09:08:28
【问题描述】:

我正在创建一个使用 Node.js 和 Express 的 RESTful API。我的应用程序使用 Oracle 数据库,所以我从 npm 安装了 node-oracledb 模块。我浏览了文档并查看了模块的 github 页面中提供的一些示例;但是,我没有看到任何使用连接池的示例。如果我错了,请纠正我,但对于将多次调用数据库的应用程序,建议使用连接池而不是使用独立连接。以下是我编写的代码示例:

createPool = function(poolAttrs, fetchPool){
  oracledb.createPool(poolAttrs, function(error, pool){
    if(error){
      console.error(`Could not create pool using specified attributes: `, error.message);
    }
    else{
      console.log(`Pool created successfully using poolAlias: ${poolAttrs.poolAlias}`);
      fetchPool(pool);
    }
  });
};

createConnection = function(poolAlias, connection){
  oracledb.getConnection(poolAlias, function(error, conn){
    if(error){
      console.error(`Could not get connection: `, error.message);
    } else {
      console.log(`New connection obtained: ${conn}`);
      connection(conn);
    }
  });
};

executeQuery = function(queryString, poolAlias){
  console.log(queryString);
  var conn = createConnection(poolAlias, function connection(conn){
    conn.execute(queryString, function(error, result){
      if(error){
        console.error(`Could not execute query: `, error.message);
      } else {
        console.log(result);
      }
      conn.close(function(error){
        if(error){
          console.error(`Could not close connection.`);
        } else {
          console.log(`Connection successfully closed.`);
        }
      })
    });
  });
}

closePool = function(pool){
  pool.close(60, function(error){
    if(error){
      console.error(`Could not close connection pool ${pool.poolAlias}`, error.message);
    } else {
      console.log(`Pool closed successfully.`);
    }
  });
};

createPool(attrs, function fetchPool(pool){
  var poolAlias = pool.poolAlias;
  console.log(poolAlias);
});

executeQuery(queryString, attrs.poolAlias);

当我运行此代码时,我收到以下错误:

Could not get connection:  NJS-047: poolAlias "amDBpool" not found in the connection pool cache

我知道为什么会发生错误。根据我对回调的理解,我知道使用 fetchPool(pool) 回调调用异步 createPool() 函数会在回调堆栈中注册此回调 (fetchPool)。所有同步代码都将在它之前执行。因此,当我调用 executeQuery 并且函数到达调用 createConnection(poolAlias...) 的执行行时,poolAlias 变量为 null,因为 createPool 函数仍在回调堆栈中等待执行。因此,不存在别名为“poolAlias”的池,并且调用失败。我知道我可以在 executeQuery 方法中调用 createPool ,但是每次执行查询时不会尝试创建一个新池吗?我的问题是,有没有办法在 executeQuery 方法内部测试池是否存在,如果不存在,则不要尝试重新创建它。除此之外,唯一的其他方法是使用 Promises 或 Async/Await 对吗?

【问题讨论】:

    标签: javascript node.js callback node-oracledb


    【解决方案1】:

    使用连接池的 node-oracledb 示例是 connectionpool.jsexamples/webap.js 文件。是的,连接池在 Web 服务中是一个好主意。另外我推荐使用异步/等待风格的编程。

    您可以看到它在执行任何其他操作之前创建了池:

    await oracledb.createPool({
      user: dbConfig.user,
      password: dbConfig.password,
      connectString: dbConfig.connectString
    });
    

    oracledb.createPool() 调用返回的池将被忽略,因为该池稍后会通过 pool cache 访问,因为没有凭据传递给 getConnection()

    let connection = await oracledb.getConnection();
    

    这使用默认池别名(恰好是字符串“default”),因此在创建或使用池时没有指定别名。

    您可能对Creating a REST API with Node.js and Oracle Database感兴趣, A node-oracledb Web Service in DockerDemo: GraphQL with Oracle Database and node-oracledb

    【讨论】:

    • 我浏览了您提供的一些帖子,并且还按照您的建议浏览了 async/await 编程示例。我将重构我的代码以合并这种新样式,看看我是否可以让它工作。
    • 我仍然不明白的一件事是你提到的关于从调用 oracledb.createPool() 中返回的池被忽略的内容。我将一个 poolAttrs 对象传递给 createPool() 方法,该方法包含数据库凭据和 poolAlias 属性。我对 oracledb.getConnection() 的调用将该别名指定为它的第一个参数,所以我认为这会从该命名连接池中获取一个连接。我指定 poolAlias 的原因是有一个命名池,但如果使用“默认”连接池可以更轻松地实现代码,那么我想我可以使用它。
    • 我的评论是关于 webappawait.js 的例子。其中,createPool() 的返回值未分配给变量,即它被忽略。这是因为池缓存是用来访问池的。
    • 我有同样的问题,即使使用你的代码hmm
    猜你喜欢
    • 2021-10-11
    • 2018-10-25
    • 2019-08-30
    • 2019-10-14
    • 2016-05-14
    • 1970-01-01
    • 2015-08-23
    • 2020-10-05
    • 2021-09-18
    相关资源
    最近更新 更多