1
votes

Let's assume we use autocommit mode, i.e.

By default (without BEGIN), PostgreSQL executes transactions in "autocommit" mode, that is, each statement is executed in its own transaction and a commit is implicitly performed at the end of the statement (if execution was successful, otherwise a rollback is done).

Then with read committed isolation level (by default in postgresql too), the statement is the actual isolation unit. But here the statement only means outer statement? What about the statements embedded in the same outer statement?

  • CTE (With queries)

I test some cases, it seems that the main query and all WITH queries share the same transaction snapshot, although some query may happen after the other due to dependency.

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

if during the whole query running, new transaction committed, should any (sub-)query here see new data?

  • statements in trigger function

It's easy to test and know that each statement within the trigger function satisfy the read committed isolation level rules, i.e. each statement would see data from all committed transactions just before it start execution.

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

if some other transaction committed after statement1, the statement2 would see the new data.

  • subquery

Consider the subquery in WHERE part, it's hard to test if each execution of subquery would see new data from other committed transactions, because the subquery would be converted into join by optimizer mostly.

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

If some other transaction committed after the second run of subquery, which modified table bar, does the third run of subquery see the new data?

I haven't read the source codes of postgresql according to this topic, does anybody know the answer?

1
What exactly is your question? Isolation levels are about visibility of changes to other transactions, not statements. - a_horse_with_no_name
sorry, I edit my question to give more description. - kingluo
A CTE or subqueries are still a single statement. - a_horse_with_no_name
so trigger is the only exception? - kingluo
I mean the isolation affect: each statement may see data from other new committed transaction than the transaction which the trigger and outer statement belongs to. - kingluo

1 Answers

1
votes

I ask the question in pgsql-general mailing list:

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

And I find the answer now:

for all the cases (trigger, CTE, other sub-query), as long as they use function written in PL, marked as VOLATILE (by default), then each query contained in the function may see new data.

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

STABLE and IMMUTABLE functions use a snapshot established as of the start of the calling query, whereas VOLATILE functions obtain a fresh snapshot at the start of each query they execute.