Re: Changing the transaction isolation level within the stored - Mailing list pgsql-sql

From Markus Schaber
Subject Re: Changing the transaction isolation level within the stored
Date
Msg-id 43D8999E.9090907@logix-tt.com
Whole thread Raw
In response to Re: Changing the transaction isolation level within the  (Mario Splivalo <mario.splivalo@mobart.hr>)
Responses Re: Changing the transaction isolation level within the stored  (Andrew Sullivan <ajs@crankycanuck.ca>)
Re: Changing the transaction isolation level within the stored  (Stephan Szabo <sszabo@megazone.bigpanda.com>)
Re: Changing the transaction isolation level within  (Mario Splivalo <mario.splivalo@mobart.hr>)
List pgsql-sql
Hi, Mario,

My explanation is a little longer, as I think I must at least basically
explain some of the fundamentals of database synchronization.

Mario Splivalo wrote:

>>>Is it possible to change the transaction level within the procedure?
>>No, currently not, the PostgreSQL "stored procedures" really are "stored
>>functions" that are called inside a query, and thus cannot contain inner
>>transactions.
> Is above true for the newly introduced stored procedures? (Above, when
> mentioning 'stored procedures' I was actualy reffering to 'functions').

I have to admit that I don't know what "newly introduced stored
procedures" you're talking about? Is this an 8.2 feature?

>>So you even want to change the transaction serialization level within a
>>running transaction? I'm sorry, this will not work, and I cannot think
>>of a sane way to make it work.
> I have some ideas, I just needed confirmation it can't be done this way.
> Thank you! :)
>>It is locically not possible to raise the isolation level when the
>>transaction was started with a lower level and thus may already have
>>irreversibly violated the constraits that the higher level wants to
>>guarantee.
> Yes, a thread will need to start a transaction, I'm just affraid that
> create_message could lead me to deadlocks.

Don't misinterpret transaction isolation as locking.

PostgreSQL (and e. G. Oracle) use a MVCC system for transactions, that
doesn't need exclusive locks.

Read-only transactions can never collide, and writing transactions only
when using transaction isolation "serializable" and manipulating the
same data rows. Some of the colliding transactions will be aborted to
resolve the conflicts, and the others can commit fine.

AFAIK, in PostgreSQL normal SQL commands cannot create deadlocks at all,
the only way to introduce deadlocks is to issue LOCK commands to take
locks manually. And for this rare case, PostgreSQL contains a deadlock
detection routine that will abort one of the insulting transactions, and
the others can proceed.

I suggest you to read "Chapter 12. Concurrency Control" from the
PostgreSLQ docs.

Its easy: if you need "read committed" guarantees, then run the entire
transaction as "read committed". If you need "serializable", then run
the entire transaction as "serializable". If you need real serialization
and synchronization of external programs, use LOCK (or take a deep
breath, redesign your application and use e. G. LISTEN/NOTIFY. Most
times, the usage of LOCK is a good indicator of misdesign.)

I just re-read your original posting. You want to make thread B wait
until thread A has committed. This will not be possible with the ACID
levels. Even when using "serializable" for both threads. If thread B
issues SELECT after thread A committed, then all works fine. If thread B
issues SELECT before thread A commits, it sees the database in the state
it was before thread A started its transaction (so even create_message
has not been called). It cannot know whether thread A will COMMIT or
ROLLBACK.

Transaction isolation is about consistency guarantees, not for true
serialization. The reason for this is that databases with high load will
need to allow paralellism.

So for your case, threas A should issue "NOTIFY" before COMMIT, and then
thread B should use LISTEN and then wait for the notification before
beginning its transaction. Be shure to read the paragraph about how
"NOTIFY interacts with SQL transactions" in the NOTIFY documentation.

I don't know the exact sematics of set_message_status and your checks,
but it may be another solution to split thread A into two transactions
by committing after step 3, and another BEGIN after step 4.

HTH,
Markus
-- 
Markus Schaber | Logical Tracking&Tracing International AG
Dipl. Inf.     | Software Development GIS

Fight against software patents in EU! www.ffii.org www.nosoftwarepatents.org


pgsql-sql by date:

Previous
From: Markus Schaber
Date:
Subject: Re: Changing the transaction isolation level within the
Next
From: Peter Eisentraut
Date:
Subject: Re: filtering after join