读取提交隔离级别的确切命令定义是什么?



假设我们使用自动提交模式,即

默认情况下(没有BEGIN),PostgreSQL在"自动提交"模式,也就是说,每条语句都以自己的方式执行事务结束时隐式执行提交语句(如果执行成功,则执行回滚)。

然后,对于读取提交的隔离级别(在postgresql中也是默认级别),该语句就是实际的隔离单元。但这里的陈述只意味着外部陈述?嵌入同一外部语句中的语句呢?

  • CTE(带查询)

我测试了一些情况,主查询和所有WITH查询似乎共享同一个事务快照,尽管由于依赖性,一些查询可能会在另一个查询之后发生。

with a as
(
statements...
),
b as (
statements depends on a, e.g. from a,
)
main query

如果在整个查询运行过程中,提交了新事务,那么这里的任何(子)查询都应该看到新数据吗?

  • 触发器函数中的语句

很容易测试并知道触发器函数中的每个语句都满足读取提交的隔离级别规则,即每个语句在开始执行之前都会看到来自所有提交事务的数据。

outer dml statement ----trigger---> foobar()
                                        statement1
                                        statement2
                                        ....

如果在语句1之后提交了其他事务,则语句2将看到新数据。

  • 子查询

考虑WHERE部分的子查询,很难测试子查询的每次执行是否会看到来自其他提交事务的新数据,因为子查询大多会由优化器转换为联接。

select * from foo where col1 > any(select col1 from bar where ....);

如果在第二次运行子查询后提交了其他事务,哪个修改了表栏,那么第三次运行子询问会看到新数据吗?

我还没有根据这个主题阅读postgresql的源代码,有人知道答案吗?

我在pgsql通用邮件列表中问了一个问题:

http://www.postgresql.org/message-id/flat/CAAc9rOz1TMme7NTb3NkvHiPjX0ckmC5UmFhadPdmXkmxagco7w@mail.gmail.com#CAAc9rOz1TMme7NTb3NkvHiPjX0ckmC5UmFhadPdmXkmxagco7w@mail.gmail.com

我现在找到了答案:

对于所有情况(触发器、CTE、其他子查询),只要他们使用PL编写的函数,标记为VOLATILE(默认情况下),然后函数中包含的每个查询都可以看到新的数据。

http://www.postgresql.org/docs/current/static/xfunc-volatility.html

STABLE和IMUTABLE函数使用在调用查询的开始,而VOLATILE函数获得新的它们执行的每个查询开始时的快照。

最新更新