我已经创建了一个表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,但令我吃惊的是没有插入任何值.我想象了一个新的子事务被函数打开,它不应该依赖于父事务.如果我对不对,请通知我
解决方法
项目列表中有一个开放的TODO项目:
> https://wiki.postgresql.org/wiki/Todo
以下是对此功能的讨论:
> http://wiki.postgresql.org/wiki/Autonomous_subtransactions
> dblink can’t update a table on the same database in an after UPDATE trigger
> How do I do large non-blocking updates in PostgreSQL?
还有一个SAVEPOINT
的相关概念(不一样的事情!):
plpython
plpython具有子事务(使用plpy.subtransaction():),但这与自治事务不同.没有单独的COMMIT.它所做的一切都是捆绑在一起,使它们成为原子.如果没有这种情况,如果异常发生在中间的某个地方,并且您捕获该异常,则只会执行直到该异常的代码.如果你把它包装成一个子交易,这是全部或全部.这就像使用SAVEPOINT而不是一个自主的事务. Per documentation:
The subtransaction context manager does not trap errors,it only assures that all database operations executed inside its scope will be atomically committed or rolled back.