在PG中,您的程序不是单独的交易。也就是说,存储过程参与现有事务。
BEGIN TRAN SELECT 1; SELECT my_proc(99); ROLLBACK TRAN;
有了这个说,你必须设置事务开始的事务级别,这是在存储过程之外。
一种选择是将服务器配置为在您最常使用的隔离区中运行,并针对与服务器设置不同的边缘情况执行SET。
事务隔离意味着您可以访问的其他concurent事务中所做的更改。
如果要序列化执行,则必须使用锁。
您可以使用行后触发和更新计数。 “UPDATE row_counts_table”将锁定表,并且所有事务都将被序列化。 的 这很慢。 强>
在您的示例中,您有两个语句。执行插入但更新必须等待其他事务,并且计数在此期间无效。
函数的语言没有任何区别。
这失败了:
test=# create function test() returns int as $$ set transaction isolation level serializable; select 1; $$ language sql; CREATE FUNCTION test=# select test(); ERROR: SET TRANSACTION ISOLATION LEVEL must be called before any query CONTEXT: SQL function "test" statement 1
请注意,在您的特定示例中,您可以使用第一个表上的触发器执行此操作。只需确保完成行计数更新 以一致的顺序 为了避免死锁,你会在可重复读取模式下做得很好。
我是标准的粉丝
PL /语言是特定于平台的。
你不能这样做。
您可以做的是让您的函数检查当前事务隔离级别是什么,如果不是您想要的那个,则中止。你可以通过运行来做到这一点 SELECT current_setting('transaction_isolation') 然后检查结果。
SELECT current_setting('transaction_isolation')