调用node-oracledb的createPool方法

Edd*_*die 1 javascript callback node.js node-oracledb

我正在创建一个使用 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);
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,出现以下错误:

Could not get connection:  NJS-047: poolAlias "amDBpool" not found in the connection pool cache
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*nes 6

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

您可以看到示例在执行其他操作之前创建了一个连接池:

await oracledb.createPool({
  user: dbConfig.user,
  password: dbConfig.password,
  connectString: dbConfig.connectString
});
Run Code Online (Sandbox Code Playgroud)

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

let connection = await oracledb.getConnection();
Run Code Online (Sandbox Code Playgroud)

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

有关使用 node-oracledb 连接池的文档和技巧位于Connection Pooling中。

您可能对使用 Node.js 和 Oracle 数据库创建 REST APIDocker 中的 Node-oracledb Web 服务和演示感兴趣:使用 Oracle 数据库和 Node-oracledb 的 GraphQL