希望是一个简单的问题,但我还没有找到一个像样的答案.我被可靠地告知,PostgreSQL(特别是9.0.4版)中的存储过程(用户定义的DB函数)本质上是事务性的,因为它们是通过SELECT语句调用的,SELECT语句本身就是事务.那么,如何 Select 存储过程的隔离级别呢?我相信在其他DBMS中,所需的事务块将被包装在一个启动事务块中,所需的隔离级别是一个可选参数.

作为一个具体的虚构例子,我想这样做:

CREATE FUNCTION add_new_row(rowtext TEXT)
RETURNS VOID AS 
$$
BEGIN
        INSERT INTO data_table VALUES (rowtext);
        UPDATE row_counts_table SET count=count+1;
END;
$$  
LANGUAGE plpgsql
SECURITY DEFINER;

想象一下,我想确保这个函数始终作为可序列化事务执行(是的,是的,PostgreSQL serializable不是适当的可序列化事务,但这不是重点).我不想要求它被称为

START TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT add_new_row('foo');
COMMIT;

那么,我如何将所需的隔离级别下推到函数中呢?我相信我不能在BEGIN声明中只把隔离级别设为the manual says

重要的是不要混淆用法

对我来说,最明显的方法是在函数定义的某个地方使用SET TRANSACTION,例如:

CREATE FUNCTION add_new_row(rowtext TEXT)
RETURNS VOID AS 
$$
BEGIN
        SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
        INSERT INTO data_table VALUES (rowtext);
        UPDATE row_counts_table SET count=count+1;
END;
$$  
LANGUAGE plpgsql
SECURITY DEFINER;

虽然这是可以接受的,但不清楚我能否依靠它来工作.SET TRANSACTIONdocumentation表示

如果执行SET事务时没有

这让我感到困惑,因为如果我调用一个单独的SELECT add_new_row('foo');语句(前提是我没有禁用autocommit),我希望SELECT以会话默认隔离级别的单行事务运行.

manual人还说:

无法设置事务隔离级别

那么,如果从隔离级别较低的事务中调用函数,会发生什么情况,例如:

START TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE row_counts_table SET count=0;
SELECT add_new_row('foo');
COMMIT;

还有一个额外的问题:函数的语言有什么不同吗?PL/pgSQL中的隔离级别设置会与普通SQL中的不同吗?

我是标准和记录在案的最佳实践的粉丝,所以任何像样的参考都将不胜感激.

推荐答案

你不能那样做.

你可以做的是让你的函数判断当前的事务隔离级别是什么,如果不是你想要的,就中止.你可以运行SELECT current_setting('transaction_isolation'),然后判断结果.

Postgresql相关问答推荐

优化PostgreSQL查询以将用户插入数据库

Postgres SQL:获取列值在连续日期之间已更改的行

为什么在使用PostGIS时,英国郡的几何图形会出现在几内亚湾?

ANTLR4 PostgreSQL语法被 destruct 了吗?

使用pg_repack从PostgreSQL中的表中删除OID

数组格式类型的PostgreSQL日期

Postgres:一次插入多行时自定义upsert(存储过程?)?

使用来自 docker 图像的 postgres 设置 Keycloak 21

Docker compose read connection reset by peer error on pipeline

我可以使用 Rails 将数组存储在 hstore 中吗

psql中set、\set和\pset的区别

在 PostgreSQL 中将时间转换为秒

SQL数据库表中的多态性?

postgresql:致命:password authentication failed for user "douglas"

在 row_to_json 函数中 Select 查询

django.db.utils.IntegrityError:duplicate key value violates unique constraint "django_content_type_pkey"

无法使用 sequelize 从本地 node 应用程序连接到 heroku postgresql 数据库

如何为查询执行设置语句超时

在 Windows 10 中执行时,Docker 容器关闭并给出data directory has wrong ownership错误

在 PostgreSQL 中 Select 进入临时表?