我遇到的情况是,我必须将一部分代码作为其自己的事务提交。
我创建了一个表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
or 2
应添加到表中subtransaction_tbl
但令我惊讶的是没有插入任何值。我想象该函数打开了一个新的子事务,它不应该依赖于父事务。请告诉我我是否正确。
Postgres 中有自治事务吗?或者我必须修改我的 plpython3u 函数吗?
Postgres确实支持嵌套事务,但它们与传统的SQL不同,更像是带有嵌套部分点的事务。
在顶层,你总是有你的典型BEGIN/COMMIT/ROLLBACK
,并且在嵌套级别上您必须使用以下命令:
-
SAVEPOINT name
- 创建一个新的保存点,其名称对于事务是唯一的
-
RELEASE SAVEPOINT name
- 提交保存点,但只有包含事务提交时它才会持续存在
-
ROLLBACK TO SAVEPOINT name
- 回滚保存点
您还必须确保:
- 每个使用的名称
SAVEPOINT
是独一无二的;
- 失败于一处
SAVEPOINT
向上传播到顶层。
最后一点有点棘手,除非您使用可以自动为您完成此操作的库。
当我写的时候pg-承诺,我确保这两项规定得到保证:
- 它自动生成保存点名称,如
sp_xy
, where x
是当前任务/事务深度,并且y
为实际交易水平+1;
- 它执行包含
ROLLBACK TO SAVEPOINT name
,加上顶层ROLLBACK
万一子交易失败 - 一切都建立在标准的承诺链逻辑之上。
另请参阅局限性PostgreSQL 嵌套事务的解释...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)