You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Knex.js事务生成有效SQL无报错,但PostgreSQL未更新数据

问题原因

你这段代码的核心问题在于forEach不支持异步等待,循环内的await不会阻塞整个循环流程。事务回调函数会在所有更新操作实际完成前就执行完毕,而Knex的事务机制会在这种情况下自动回滚事务,最终导致数据库没有任何变更。

虽然Knex调试器显示每个更新语句都正常生成,但因为事务被自动回滚了,这些变更根本没被提交到数据库。而直接执行原生SQL时没有事务上下文,所以变更能正常生效。

修复方案

方案一:使用for...of循环(串行更新)

把forEach替换成支持异步等待的for...of,确保所有更新操作完成后事务才会提交:

const updatedLocations = await knex.transaction(async (trx) => {
  for (const location of locations) {
    location.entry_id = entry.id;
    await trx("locations").update(location).where("id", location.id);
  }
});

方案二:使用Promise.all并行更新

如果你的更新操作之间没有依赖关系,可以用Promise.all并行执行所有更新,提升效率:

const updatedLocations = await knex.transaction(async (trx) => {
  await Promise.all(locations.map(async (location) => {
    location.entry_id = entry.id;
    return trx("locations").update(location).where("id", location.id);
  }));
});
额外注意点
  • 别忘了在knex.transaction前加上await,这样可以正确捕获事务中的异常,也能确保后续代码在事务完成后再执行。
  • 如果你需要更精细的控制,可以显式调用trx.commit()或trx.rollback(),但只要回调函数返回的Promise被正确resolve,Knex会自动提交事务。

内容的提问来源于stack exchange,提问作者NYCaver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 17:15:37