gpt4 book ai didi

mysql - NodeJS mysql连接池与多个查询

转载 作者:太空宇宙 更新时间:2023-11-03 23:17:08 25 4
gpt4 key购买 nike

我对 NodeJS 相当陌生(有 PHP 背景)。与 PHP 的阻塞性质相比,我对 NodeJS 的异步性质有了基本的了解。我创建了一些连接到 mysql 的应用程序 Node 并使其正常工作。

我目前对在 Node 中执行查询的最佳方式的理解是这样的:

  • 创建连接池
  • 当您需要执行查询时:
  • 从池中获取Connection()
  • 执行查询
  • .release() 连接

我面临的情况是,我需要迭代大量项目并将每个项目插入数据库。执行上述操作并没有成功。我的想法是,由于每个查询都是并行执行的,因此列表中的下一项试图获取连接,但没有一个可用,因为之前的查询可能尚未完成。没有抛出任何错误,只是似乎没有放入项目。通过日志记录,我发现它从未达到运行 pool.getConnection() 回调的程度。

所以我认为我可以修改连接流程:

  • 创建连接池
  • 当您需要执行许多查询时:
  • 从池中获取Connection()
  • 迭代需要查询的项目
  • 执行查询
  • .release() 连接

问题是,我如何知道何时可以安全地 .release() 我的连接?我不能只在 .query() 回调中执行此操作,因为后面可能会有更多查询。但我也不能不在查询回调中执行此操作,因为我知道我需要等待所有查询完成。我是否负责创建自己的逻辑来确定所有查询(以及所有可能的 future 查询,即使它们尚未开始)何时完成?或者这只是尚未完成的事情?

在 PHP 中,由于它的阻塞性质,这将是微不足道的。我选择在这个应用程序中使用 NodeJS,因为它有时确实需要异步。但它在我的应用程序不需要它的地方强制我异步(在某些情况下不应该使用它)。

我犹豫是否要发布我的代码,因为它有点复杂,所以我不想分散对这个特定主题的注意力。

最佳答案

您的连接流程正常。如果您只执行 1 个查询,则实际上不需要执行任何步骤,只需直接在池上调用 .query() 即可。 (其余的在幕后完成)。

大多数情况下需要在1个事务中进行多个查询,但我会添加事务支持:

  • 创建连接池
  • 当您需要执行许多查询时:
  • 从池中获取Connection()
  • 开始交易
  • 迭代需要查询的项目
  • 执行查询
  • 如果有任何失败,请停止并回滚
  • 如果全部成功,则提交
  • .release() 连接

如果所有查询都“完成”,您知道何时释放连接。你怎么知道它已经完成了?有不止一种方法。我建议您使用 Promise API,因此它可能如下所示:

async function doStuff(items) {

try {
const connection = await pool.getConnection();
await connection.beginTransaction();
for(const item of items) {
await connection.query('....');
}
await connection.commit();
} catch (e) {
await connection.rollback();
throw e;
} finally {
await connection.release();
}

}

这种模式有一些优点:

  1. 它将正确报告错误
  2. 它将在成功和错误时释放连接。
  3. 要么完全失败,要么完全成功。这里没有半途而废。

如果你不关心交易,这可以简化:

async function doStuff(items) {

try {
const connection = await pool.getConnection();
for(const item of items) {
await connection.query('....');
}
} finally {
await connection.release();
}

}

这样做的问题是您可能会获得部分成功,这通常是不可取的,尤其是对于 API 而言。不过,如果它对您来说足够好,那就足够了。

如果您愿意不进行交易,理论上您可以完全跳过 getConnection 步骤:

async function doStuff(items) {
for(const item of items) {
await pool.query('....');
}
}

这意味着您的所有查询可能在不同的连接上执行。这可能会给您带来更差的性能,但会使代码更简单。

如何启用 Promise?

这有点争议。为此,您可能需要切换 mysql 软件包。有一个 mysql2 包,它具有非常出色的 mysql2/promise 导入(并且实际上与更流行的 mysql 包共享代码)。 super 建议切换到这个。

如果我不想切换套餐怎么办?

嗯,回调版本要痛苦得多。在这种情况下,我建议仍然使用 promise ,但将回调转换为 promise 模式,也许使用“promisify”。

如果您确实不想在任何地方使用 Promise,那么您基本上必须将我的示例转换为基于回调的示例,这看起来会更加痛苦。

关于mysql - NodeJS mysql连接池与多个查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54011512/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com