Postgres 支持嵌套或自治事务吗?

问题描述 投票:0回答:3

我遇到过这样的情况:我必须将一部分代码作为其自己的事务提交。
我创建了一个表

subtransaction_tbl
:

CREATE TABLE subtransaction_tbl
(
  entryval integer
)

以及 plpython3u 语言中的函数:

CREATE FUNCTION subtransaction_nested_test_t() RETURNS void
AS $$
plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
with plpy.subtransaction():
    plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
$$ LANGUAGE plpython3u;

第一种情况:

BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select  subtransaction_nested_test_t();
COMMIT TRANSACTION;

表格中的条目正确:1,2,4

第二种情况:

BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select  subtransaction_nested_test_t();
ROLLBACK TRANSACTION;

表中的值未填充

我预计

1
2
应添加到表
subtransaction_tbl
但令我惊讶的是没有插入任何值。我想象该函数打开了一个新的子事务,它不应该依赖于父事务。请告诉我我的说法是否正确。

Postgres 中有自治事务吗?或者我必须修改我的 plpython3u 函数吗?

sql postgresql python-3.x transactions
3个回答
42
投票

Postgres确实支持嵌套事务,但它们与传统的SQL不同,更像是带有嵌套部分点的事务。

在顶层,您始终具有典型的

BEGIN/COMMIT/ROLLBACK
,在嵌套级别上,您必须使用以下命令:

  • SAVEPOINT name
    - 创建一个新的保存点,其名称对于事务来说是唯一的
  • RELEASE SAVEPOINT name
    - 提交保存点,但只有包含事务提交时它才会持续存在
  • ROLLBACK TO SAVEPOINT name
    - 回滚保存点

您还必须确保:

  • 每个
    SAVEPOINT
    使用的名称都是唯一的;
  • 其中一个
    SAVEPOINT
    的失败会向上传播到顶层。

最后一点有点棘手,除非您使用可以自动为您完成此操作的库。

当我写下pg-promise时,我确保这两个条款得到保证:

  • 它自动生成保存点名称,如
    sp_xy
    ,其中
    x
    是当前任务/事务深度,
    y
    是实际事务级别+1;
  • 它执行包含
    ROLLBACK TO SAVEPOINT name
    ,加上顶级
    ROLLBACK
    ,以防子事务失败 - 所有这些都建立在标准的承诺链逻辑上。

另请参阅 PostgreSQL 嵌套事务的限制解释...


29
投票

在 Postgres 11 之前,Postgres 中没有自治事务,其中添加了 SQL 过程。参见:

函数中完成的所有操作都随事务一起提交或回滚。

在 Postgres 10 或更早版本中,解决方法可能是(ab-)使用 dblink:

还有一个

SAVEPOINT
的相关概念。 (不是同一件事!):

plpython

plpython 有 子事务 (

with plpy.subtransaction():
),但这与自治事务不同。没有单独的
COMMIT
。它所做的就是将几个语句捆绑在一起,使它们成为原子的。如果没有这个,如果中间某个地方发生异常,并且您捕获该异常,则只会执行该异常之前的代码。如果将其包装到子事务中,则要么全有,要么全无。这就像使用
SAVEPOINT
,而不是自主交易。 手册

子事务上下文管理器不会捕获错误,它只会捕获错误 确保在其范围内执行的所有数据库操作都将 原子提交或回滚。

以下是对该功能的讨论:


0
投票

@SarthAk 这是一个支持自主交易(WIP)的补丁。如果你愿意,你可以修补 Postgres master 源代码并编译

https://www.postgresql.org/message-id/flat/f7470d5a-3cf1-4919-8404-5c4d91341a9f%40tantorlabs.com

FOSSAsia 的视频及说明:

https://youtu.be/JC4uZVLVcBU?t=11066

© www.soinside.com 2019 - 2024. All rights reserved.