Are PostgreSQL functions transactional?
PostgreSQL函数如下面的自动事务是什么?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | CREATE OR REPLACE FUNCTION refresh_materialized_view(name) RETURNS INTEGER AS $BODY$ DECLARE _table_name ALIAS FOR $1; _entry materialized_views%ROWTYPE; _result INT; BEGIN EXECUTE 'TRUNCATE TABLE ' || _table_name; UPDATE materialized_views SET last_refresh = CURRENT_TIMESTAMP WHERE TABLE_NAME = _table_name; RETURN 1; END $BODY$ LANGUAGE plpgsql VOLATILE SECURITY DEFINER; |
换句话说,如果在执行函数期间发生错误,是否会回滚任何更改? 如果这不是默认行为,我该如何使该函数成为事务性的?
PostgreSQL 12更新:对可以进行事务控制的顶级
函数是他们调用的事务的一部分。如果事务回滚,它们的效果将被回滚。如果事务提交,他们的工作将提交。函数中的任何
除了
1 2 3 4 5 6 | regress=# BEGIN; BEGIN regress=# SELECT 1/0; ERROR: division BY zero regress=# COMMIT; ROLLBACK |
看看由于零分割而处于错误状态的事务如何在
如果在没有明确的外围事务的情况下调用函数,则规则与任何其他Pg语句完全相同:
1 2 3 | BEGIN; SELECT refresh_materialized_view(name); COMMIT; |
(如果
PostgreSQL(还)不支持函数中的自治事务,其中过程/函数可以独立于调用事务提交/回滚。这可以通过dblink使用新会话进行模拟。
但是,PostgreSQL中存在非事务性或不完全事务性的事物。如果它在正常的
由于我对PostgreSQL的了解不如Craig Ringer那么深,我会尝试给出一个较短的答案:是的。
如果执行其中包含错误的函数,则任何步骤都不会影响数据库。
此外,如果您在
例如,如果您在查询中执行:
1 2 3 | UPDATE your_table yt SET column1 = 10 WHERE yt.id=20; SELECT anything_that_do_not_exists; |
更新于2008年9月至2018年
为了澄清这个概念,我用非事务函数nextval做了一个小例子。
首先,让我们创建一个序列:
然后,让我们执行:
select nextval('test_sequence');
select anything_that_do_not_exists;
现在,如果我们打开另一个查询并执行
我们将获得101因为第一个值(100)在后一个查询中使用(这是因为序列不是事务性的),尽管未提交更新。
在功能层面,它不是跨国的。换句话说,函数中的每个语句都属于单个事务,这是默认的db auto commit值。默认情况下,自动提交为true。但无论如何,你必须使用函数调用
上面的语句'select schemaName.functionName()'是单个事务,让我们将事务命名为T1,因此函数中的所有语句都属于事务T1。通过这种方式,该功能处于单个事务中。
https://www.postgresql.org/docs/current/static/plpgsql-structure.html
It is important not to confuse the use of BEGIN/END for grouping statements in PL/pgSQL with the similarly-named SQL commands for transaction control. PL/pgSQL's BEGIN/END are only for grouping; they do not start or end a transaction. Functions and trigger procedures are always executed within a transaction established by an outer query — they cannot start or commit that transaction, since there would be no context for them to execute in. However, a block containing an EXCEPTION clause effectively forms a subtransaction that can be rolled back without affecting the outer transaction. For more about that see Section 39.6.6.