我们假设我们使用自动提交模式,即
默认情况下(没有BEGIN),PostgreSQL在中执行事务 "自动提交"模式,即每个语句都是自己执行的 事务和提交是在结尾隐式执行的 语句(如果执行成功,否则回滚完成)。
然后使用read committed isolation level(默认情况下也在postgresql中),该语句是实际的隔离单元。但这里的陈述只意味着外在声明?嵌入在同一外部声明中的语句怎么样?
我测试了一些情况,似乎主查询和所有WITH查询共享相同的事务快照,尽管由于依赖性,某些查询可能会在另一个之后发生。
with a as
(
statements...
),
b as (
statements depends on a, e.g. from a,
)
main query
如果在整个查询运行期间,提交了新事务,那么这里的任何(子)查询是否应该看到新数据?
它易于测试并且知道触发器函数中的每个语句都满足读取提交的隔离级别规则,即每个语句在开始执行之前都会看到来自所有已提交事务的数据。
outer dml statement ----trigger---> foobar()
statement1
statement2
....
如果在statement1之后提交了一些其他事务,则statement2将看到新数据。
考虑WHERE部分中的子查询,如果子查询的每次执行都会看到来自其他已提交事务的新数据,则很难测试,因为子查询主要由优化器转换为连接。
select * from foo where col1 > any(select col1 from bar where ....);
如果在第二次子查询运行后提交了一些其他事务(修改了表格栏),第三次子查询运行是否会看到新数据?
我还没有根据这个主题阅读postgresql的源代码,有人知道答案吗?
答案 0 :(得分:1)
我在pgsql-general邮件列表中提问:
我现在找到了答案:
用于所有情况(触发器,CTE,其他子查询),只要 它们使用PL中写的函数,标记为VOLATILE(默认情况下),然后 函数中包含的每个查询都可以看到新数据。
http://www.postgresql.org/docs/current/static/xfunc-volatility.html
STABLE和IMMUTABLE函数使用从中创建的快照 调用查询的开始,而VOLATILE函数获得新鲜 快照在每个查询开始时执行。