Sar*_*hAk 17 sql postgresql transactions python-3.x
我有一种情况,我必须提交一部分代码作为自己的事务.
我创建了一个表subtransaction_tbl
:
CREATE TABLE subtransaction_tbl
(
entryval integer
)
Run Code Online (Sandbox Code Playgroud)
和语言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;
Run Code Online (Sandbox Code Playgroud)
第一种情况:
BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select subtransaction_nested_test_t();
COMMIT TRANSACTION;
Run Code Online (Sandbox Code Playgroud)
表中的条目是正确的:1,2,4
第二种情况:
BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select subtransaction_nested_test_t();
ROLLBACK TRANSACTION;
Run Code Online (Sandbox Code Playgroud)
表中的值未填充
我预计1
或2
应该添加到表中,subtransaction_tbl
但令我惊讶的是没有插入任何值.我想象一个新的子事务由函数打开,它不应该依赖于父事务.如果我是对的,请告诉我.
Postgres有自动交易吗?或者我是否必须修改我的plpython3u函数?
vit*_*y-t 19
Postgres确实支持嵌套事务,但它们与传统SQL不同,更像是具有嵌套部分点的事务.
在顶层,您始终拥有典型的BEGIN/COMMIT/ROLLBACK
,在嵌套级别上,您必须使用以下命令:
SAVEPOINT name
- 创建一个新的保存点,其名称对于事务是唯一的RELEASE SAVEPOINT name
- 提交保存点,但只有在包含事务提交时才会保留ROLLBACK TO SAVEPOINT name
- 回滚保存点您还必须确保:
SAVEPOINT
都是唯一的;SAVEPOINT
向上传播到顶层.最后一点有点棘手,除非您使用可以自动为您执行此操作的库.
当我写pg-promise时,我确保这两项规定得到保证:
level_1
,level_2
等等;ROLLBACK TO SAVEPOINT name
,以及在ROLLBACK
子事务失败的情况下的顶级- 所有这些都构建在标准的promise-chaining逻辑上.另请参阅解释的PostgreSQL嵌套事务的局限性 ......
Erw*_*ter 18
Postgres 中没有自动交易,包括Postgres 9.4.在该函数中完成的所有操作都将与事务一起回滚.
项目列表中有一个打开的TODO项:
以下是对该功能的讨论:
目前,解决方法可能是(ab-)使用dblink:
还有一个相关的概念SAVEPOINT
.(不一样!):
plpython有subtransactions(with plpy.subtransaction():
),但这与自治事务不同.没有单独的COMMIT
.它所做的只是将几个语句捆绑在一起,使它们成为原子.如果没有它,如果异常发生在中间某处,并且您捕获该异常,则只会执行此异常的代码.如果将它包装成子事务,则全部或全部.这就像使用a SAVEPOINT
,而不是自治事务.每个文件:
子事务上下文管理器不会捕获错误,它只确保在其作用域内执行的所有数据库操作都将以原子方式提交或回滚.
归档时间: |
|
查看次数: |
19559 次 |
最近记录: |