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
相关产品推荐
相关产品推荐

