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

pg-promise事务回滚后插入数据仍留存的原因咨询

问题根源:事务内用错了执行对象

嘿,我一眼就揪出问题所在了——你在事务上下文里用错了执行对象!

你遇到的核心问题很直接:在db.tx()创建的事务环境中,你调用了全局的db.any()方法,而非事务对象t上的对应方法。

pg-promise的事务机制里,db.tx()返回的事务对象t才是绑定当前事务会话的唯一入口。所有需要纳入事务管理的SQL操作,都必须通过这个t对象来执行(比如t.any()、t.none()等)。如果直接用db对象执行查询,这些操作会创建全新的独立数据库连接,完全不受当前事务的控制——不管事务最后是提交还是回滚,这些独立执行的插入都会直接提交到数据库里,自然不会被回滚影响。

修正后的代码示例

把你的代码里的db.any()替换成t.any(),就能让操作真正纳入事务管理了:

testFunction: (req, res, next) => { 
  db.tx(async t =>{ 
    // 用t.any()替代db.any(),绑定到当前事务会话
    await t.any('insert into services (servicename, price, itemcode, servicedescription, active, subscriptionid) values ($1, $2, $3, $4, $5, $6) returning *;', ['babysitting', 25, '12321', 'taking care of children', true, 1]) 
    await t.any('insert into orangutans (name, age, sex)...') // 同样替换成t.any()
    // 如需返回结果,可在这里return对应数据
  })
  .then(result => {
    // 事务成功提交后的处理逻辑
    res.send('事务执行成功')
  })
  .catch(error => {
    // 事务触发回滚后的处理,此时两个插入操作都会被撤销
    next(error)
  })
}

额外注意事项

  • 事务函数内部如果抛出任何错误(包括异步操作的reject),pg-promise都会自动触发回滚;如果函数正常执行完成,则自动提交事务。
  • 务必确保事务内的所有数据库操作都通过事务对象t执行,不要混用全局的db对象,否则就会脱离事务的原子性控制。
  • 如果你的第二个插入语句存在语法错误或约束违反,修正后的代码会自动回滚第一个插入的内容,这正是事务机制要保证的原子性效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:34:34