Dón*_*nal 66 postgresql transactions
PostgreSQL函数如下面的自动事务是什么?
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;
Run Code Online (Sandbox Code Playgroud)
换句话说,如果在执行函数期间发生错误,是否会回滚任何更改?如果这不是默认行为,我该如何使该函数成为事务性的?
Cra*_*ger 78
函数是他们调用的事务的一部分.如果事务回滚,它们的效果将被回滚.如果事务提交,他们的工作将提交.PROCEDURE
函数中的任何块都像(和在引擎盖下使用)一样运行保存点,如SQL语句BEGIN ... EXCEPT
和SAVEPOINT
SQL语句.
除了ROLLBACK TO SAVEPOINT
错误处理之外,该功能要么全部成功要么全部失败.如果在函数内引发错误而未处理,则中止调用该函数的事务.中止的事务无法提交,如果它们尝试提交,BEGIN ... EXCEPT
则视为与COMMIT
错误的任何其他事务相同.注意:
regress=# BEGIN;
BEGIN
regress=# SELECT 1/0;
ERROR: division by zero
regress=# COMMIT;
ROLLBACK
Run Code Online (Sandbox Code Playgroud)
看看由于零分割而处于错误状态的事务如何回滚ROLLBACK
?
如果在没有明确的外围事务的情况下调用函数,则规则与任何其他Pg语句完全相同:
BEGIN;
SELECT refresh_materialized_view(name);
COMMIT;
Run Code Online (Sandbox Code Playgroud)
(COMMIT
如果COMMIT
引发错误,将在哪里失败).
PostgreSQL(还)不支持函数中的自治事务,其中过程/函数可以独立于调用事务提交/回滚.这可以通过dblink使用新会话进行模拟.
但是,PostgreSQL中存在非事务性或不完全事务性的事物.如果它在正常SELECT
块中具有非事务性行为,则它在函数中也具有非事务性行为.例如,BEGIN; do stuff; COMMIT;
和nextval
,setval
等.
Ign*_*cio 26
由于我对PostgreSQL的了解不如Craig Ringer那么深,我会尝试给出一个更简短的答案:是的.
如果执行其中包含错误的函数,则任何步骤都不会影响数据库.
此外,如果您执行同一个查询PgAdmin
.
例如,如果您在查询中执行:
update your_table yt set column1 = 10 where yt.id=20;
select anything_that_do_not_exists;
Run Code Online (Sandbox Code Playgroud)
该行的更新id = 20
的your_table
不会被保存在数据库中.
更新于2008年9月至2018年
为了澄清这个概念,我用非事务函数nextval做了一个小例子.
首先,让我们创建一个序列:
create sequence test_sequence start 100;
然后,让我们执行:
update your_table yt set column1 = 10 where yt.id=20;
select nextval('test_sequence');
select anything_that_do_not_exists;
现在,如果我们打开另一个查询并执行
select nextval('test_sequence');
我们将获得101因为第一个值(100)在后一个查询中使用(这是因为序列不是事务性的),尽管未提交更新.
小智 6
https://www.postgresql.org/docs/current/static/plpgsql-structure.html
重要的是不要混淆使用BEGIN / END将PL / pgSQL中的语句与类似名称的SQL命令进行事务控制进行分组。PL / pgSQL的BEGIN / END仅用于分组;他们不开始或结束交易。函数和触发器过程始终在由外部查询建立的事务中执行-它们无法启动或提交该事务,因为将没有上下文可在其中执行。但是,包含EXCEPTION子句的块有效地形成了一个子事务,该子事务可以在不影响外部交易的情况下回滚。有关更多信息,请参见第39.6.6节。
在功能层面,它不是跨国的.换句话说,函数中的每个语句都属于单个事务,这是默认的db auto commit值.默认情况下,自动提交为true.但无论如何,你必须使用函数调用
select schemaName.functionName()
上面的语句'select schemaName.functionName()'是单个事务,让我们将事务命名为T1,因此函数中的所有语句都属于事务T1.通过这种方式,该功能处于单个事务中.
归档时间: |
|
查看次数: |
40515 次 |
最近记录: |