On 04/11/14 09:07, Craig Ringer wrote:
On 11/04/2014 07:31 AM, Álvaro Hernández Tortosa wrote:
     Thank you for your comment, Tom. However I think this behavior, as
seen from a user perspective, it's not the expected one.
That may be the case, but I think it's the SQL-standard behaviour, so we
can't really mess with it.

The spec requires SET TRANSACTION ISOLATION, and you can't implement
that if you take a snapshot at BEGIN.

It's true that the standard mandates SET TRANSACTION rather than setting the isolation level with the BEGIN statement, and in any case you can raise/lower the isolation level with SET regardless of what the session or the begin command said. However, is it really a problem taking a snapshot at BEGIN time --only if the tx is started with BEGIN ... (REPEATABLE READ | SERIALIZABLE)? AFAIK, and I may be missing some internal details here, the worst that can happen is that you took one extra, unnecessary snapshot. I don't see that as a huge problem.

The standard (92) says that transaction is initiated when a transaction-initiating SQL-statement is executed. To be fair, that sounds to me more of a "SELECT" rather than a "BEGIN", but I may be wrong.

     If it is still the intended behavior, I think it should be clearly
documented as such, and a recommendation similar to "issue a 'SELECT 1'
right after BEGIN to freeze the data before any own query" or similar
comment should be added. Again, as I said in my email, the documentation
clearly says that "only sees data committed before the transaction
began". And this is clearly not the real behavior.
It's more of a difference in when the transaction "begins".

Arguably, "BEGIN" says "I intend to begin a new transaction with the
next query" rather than "immediately begin executing a new transaction".

This concept could be clearer in the docs.

If this is really how it should behave, I'd +1000 to make it clearer in the docs, and to explicitly suggest the user to perform a query discarding the results early after BEGIN if the user wants the state freezed if there may span time between BEGIN and the real queries to be executed (like doing a SELECT 1).


     Sure, there are, that was the link I pointed out, but I found no
explicit mention to the fact that I'm raising here.
I'm sure it's documented *somewhere*, in that I remember reading about
this detail in the docs, but I can't find _where_ in the docs.

It doesn't seem to be in:

http://www.postgresql.org/docs/current/static/transaction-iso.html

where I'd expect.

    Yepp, there's no mention there.


In any case, we simply cannot take the snapshot at BEGIN time, because
it's permitted to:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

in a DB that has default serializable isolation or has a SET SESSION
CHARACTERISTICS isolation mode of serializable. Note that SET
TRANSACTION is SQL-standard.

As I said, AFAIK it shouldn't matter a lot to take the snapshot at BEGIN. The worst that can happen is that you end up in read committed and you need to take more snapshots, one per query.


AFAIK deferring the snapshot that's consistent with other RDBMSes that
use snapshots, too.

I tried Oracle and SQL Server. SQL Server seems to behave as PostgreSQL, but just because it locks the table if accessed in a serializable transaction, so it definitely waits until select to lock it. However, Oracle behaved as I expected: data is frozen at BEGIN time. I haven't tested others.



The docs of that command allude to, but doesn't explicitly state, the
behaviour you mention.

http://www.postgresql.org/docs/current/static/sql-set-transaction.html



Should we improve then the docs stating this more clearly? Any objection to do this?

    Regards,

    Álvaro


--
Álvaro Hernández Tortosa


-----------
8Kdata



--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to