Thread: SetQuerySnapshot in 7.4

SetQuerySnapshot in 7.4

From
Max Jacob
Date:
Hallo to everybody.

I have found out that statements in a function beheave differently than 
"root" statements due to the fact that statements inside a function do 
not update the db snapshot.
I already read the discussions in the archieve before 7.3 release, but i 
still disagree strongly with this behaviour!
As a very simple example, if i select for update a row in a function, it 
correctly waits for a commit of other transactions that lock that row, 
but after this the row is still the same than before !! So at least 
there is an inconsistence (i could not have been locked, since i 
continue on seeing the same thing than before the changes).
But things get really bad in the following case. Suppose i want to write 
a function that checks (before doing some manipulation on it) if a row 
with a given primary key exists. If not it insterts it. Now, there is no 
way to write such a function in a safe way, since even if before 
inserting the row it locks the whole table in exclusive mode, another 
concurrent call to the same function would:   1- wait on the select for update untill the first call has committed   2-
verifythat the row does not exists (since irt still sees the 
 
previous snapshot)   3- insert it causing an error because it tries to insert a duplicate 
primary key

All this without considering the really non-intuitive fact that if i try 
to simulate step by step the same thing on two psql terminals (giving 
the commands one by one, i mean), it beheaves differently (it works fine 
without any error)!!!

I checked out if there is some discussion on this for the 7.4, but could 
not find anything, so i ask directly: is there some reconsideration on 
this issue? (if it affects too much performance, it could be an option).
Personally i would strongly suggest it, and i really apologize on not 
having (yet) the time to really dive into postgresql sources to 
contribute myself on this point instead of asking like this.

Thanks to everybody (especially to all developpers since this is really 
the only point i don't like in postgres!)

Max.




Re: SetQuerySnapshot in 7.4

From
Robert Treat
Date:
On Thu, 2003-09-11 at 11:57, Max Jacob wrote:
> Hallo to everybody.
> 
> I have found out that statements in a function beheave differently than 
> "root" statements due to the fact that statements inside a function do 
> not update the db snapshot.
> I already read the discussions in the archieve before 7.3 release, but i 
> still disagree strongly with this behaviour!
> As a very simple example, if i select for update a row in a function, it 
> correctly waits for a commit of other transactions that lock that row, 
> but after this the row is still the same than before !! So at least 
> there is an inconsistence (i could not have been locked, since i 
> continue on seeing the same thing than before the changes).
> But things get really bad in the following case. Suppose i want to write 
> a function that checks (before doing some manipulation on it) if a row 
> with a given primary key exists. If not it insterts it. Now, there is no 
> way to write such a function in a safe way, since even if before 
> inserting the row it locks the whole table in exclusive mode, another 
> concurrent call to the same function would:
>     1- wait on the select for update untill the first call has committed
>     2- verify that the row does not exists (since irt still sees the 
> previous snapshot)
>     3- insert it causing an error because it tries to insert a duplicate 
> primary key
> 
> All this without considering the really non-intuitive fact that if i try 
> to simulate step by step the same thing on two psql terminals (giving 
> the commands one by one, i mean), it beheaves differently (it works fine 
> without any error)!!!
> 
> I checked out if there is some discussion on this for the 7.4, but could 
> not find anything, so i ask directly: is there some reconsideration on 
> this issue? (if it affects too much performance, it could be an option).
> Personally i would strongly suggest it, and i really apologize on not 
> having (yet) the time to really dive into postgresql sources to 
> contribute myself on this point instead of asking like this.
> 
> Thanks to everybody (especially to all developpers since this is really 
> the only point i don't like in postgres!)
> 

There is no discussion of it that I am aware of. Most of the push back
against this behavior seems to stem from a concern that changing this
behavior could cause unforeseen problems down the road. Personally I
find this a weak argument since the change would solve a currently known
problem, and doesn't seem to introduce any immediate problems.  There
are two proposed changes I am aware of: one would be to have functions
do a new setQuerySnapshot whenever they acquire a lock, the other would
be to add a new keyword to the function semantics to allow some
functions to call setQuerySnapshot just as if all internal sql
statements were running in read committed mode. The first seems like the
easier to implement, though I think some don't feel it is an elegant
solution. The second would be more powerful, but exactly how to
implement it seems mysterious (the one good explanation I heard required
nested transactions). Personally I would love to see some work done on
this, I think it's a major lacking in the postgresql function support. 

Robert Treat
-- 
Build A Brighter Lamp :: Linux Apache {middleware} PostgreSQL