【问题标题】:Postgresql - restore to savepoint across transaction boundariesPostgresql - 跨事务边界恢复到保存点
【发布时间】:2020-04-09 18:03:23
【问题描述】:

有没有办法回滚到“提交的保存点”?

Afaik,postgresql 支持的实际保存点是子事务,当封闭事务提交或中止时,它们就失去了意义。是否存在跨事务边界的“保存点”?

基本上,我想要的是按顺序执行这三个事务:

交易~A

BEGIN TRANSACTION;
    COMMIT SAVEPOINT 'before_a';
    DO SOMETHING;
COMMIT TRANSACTION;

交易~B

BEGIN TRANSACTION;
    DO SOMETHING_ELSE;
COMMIT TRANSACTION;

交易~C

BEGIN TRANSACTION
    ROLLBACK TO COMMITED SAVEPOINT 'before_a'; -- discards work done in A and B
COMMIT TRANSACTION

原因是我正在编写(Java)回归测试。

在错误的情况下,DO SOMETHING_ELSE 将在尝试提交 B 时触发事务提交异常(我相信在 DELETE 时会违反一些外键约束),但前提是事务 A 中完成的工作已经提交。

由于问题现已解决,事务 B 将提交。 但是这样做,A 和 B 都会在数据库中留下一些副产品。 如果下一次测试应该有任何成功的机会,现在需要从数据库中清除这些。

手动追踪这些副产品非常困难,因此事务 C 应该删除这些副产品。

【问题讨论】:

  • 你无法为所欲为。 commit 使迄今为止的所有交易更改永久化。保存点总是对于创建它们的事务来说是本地的。无法访问在不同事务中创建的保存点(更不用说回滚到它了)
  • @a_horse_with_no_name 这就是为什么我把它放在引号里。我正在寻找可以从 postgresql 中提供此功能的任何半合理机制。
  • 在单个事务中运行整个事情。所以“开始 Do_Something;Do_Something_Else;回滚;结束;”只要事务正在运行,Do_Something_Else 就可以看到在 Do_Something 期间所做的任何数据库更改”。不幸的是,您无法进入事务以验证已完成的操作。另一个选项,如果您在测试环境中,将在之前备份并在之后恢复.

标签: postgresql transactions rollback postgresql-9.6 savepoints


【解决方案1】:

正如 cmets 中提到的,这在 PostgreSQL 中是不可能的。

您唯一的希望是在封装事务中使用子事务:

BEGIN;
SAVEPOINT before_a;
/* perform the work for A */
/* perform the work for B */

如果 B 失败,请执行以下操作:

ROLLBACK TO SAVEPOINT before_a;

那么,不管B失败与否:

/* perform the work for C */
COMMIT;

【讨论】:

    猜你喜欢
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多