所谓事务,是指将多个SQL语句封装在一个(例如)begin isolation level serializable
块中。并发事务可能会使此事务失败,即回滚。
如何在PostgreSQL中重新启动失败的事务?
所谓事务,是指将多个SQL语句封装在一个(例如)begin isolation level serializable
块中。并发事务可能会使此事务失败,即回滚。
如何在PostgreSQL中重新启动失败的事务?
ROLLBACK
是必需的;如果你不这样做,那么该连接上的任何进一步操作都会失败,并显示“事务中止”错误。node-postgres
是异步和非阻塞的,因此不太可能抛出异常;你应该寻找一个函数,让你查询会话中最后一个操作的结果 SQLSTATE
和客户端驱动程序的错误状态。
node-postgres
似乎没有充足的文档资料,所以您最好查看 node-postgres
的源代码或找到其他人如何处理此类问题的示例。我相信您会找到检查会话错误状态的函数。您需要寻找的是一个函数来获取连接上最后一次操作的 SQLSTATE
。
值得注意的是,可以发布一个专门关注如何检测和处理 node-postgres
中错误的问题。
1实际上,SAVEPOINT
和ROLLBACK TO SAVEPOINT
可以让您做到这一点,但它们不能帮助处理序列化错误。
这个答案是在3年后添加的,以考虑到此期间的变化。尽管原始答案仍然有效,但这个答案展示了如何使用当时不可用的正确工具来轻松完成。
BEGIN
->COMMIT
/ROLLBACK
表示,而所有嵌套事务都会自动变成SAVEPOINT
。db.tx(t => {
// BEGIN
// top-level changes cannot be restarted:
return t.any('UPDATE users SET name=$1 WHERE id=$2', ['Mike', 123])
.then(() => {
return t.tx(t1 => {
// SAVEPOINT
return t1.none('INSERT log(event) VALUES($1)', 'entry');
})
.catch(error => {
// ROLLBACK TO SAVEPOINT executed
return t.none('UPDATE log SET event = $1');
});
});
})
.then(data => {
// success, COMMIT executed
})
.catch(error => {
// error, ROLLBACK executed
});
UPDATE
操作,由于这个原因不能重新启动。然后我们进行了嵌套事务/保存点,其中包括一个INSERT
,如果失败,则再次替换为顶层的UPDATE
。SAVEPOINT
失败,我们仍然可以成功完成顶层事务。