![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
CREATE OR REPLACE FUNCTION test_tr() RETURNS numeric AS' DECLARE a numeric; b numeric; BEGIN select next_number into b from test_trans where id=1; update test_trans set next_number=next_number+1 where id=1; select next_number into a from test_trans where id=1; RETURN a ; END; ' LANGUAGE 'plpgsql' VOLATILE; What I do then. I've run two sessions. In first I've run test_trans(), then in second I've run test_trans() too. Second sessions waiting for first commit or rollback. Very good. Then I've commited first session. What I see then: First session returned value 2 - very good, but second session returned value 1 - poor, oooo poor. Why , why, why? Second session should returned value 3. What happends. In version 8.0 Beta is the same situation. Additionl info: I've must user read commited transacion isolation. Please answer for my problem. My application based on this database but this problem show everyone that PostgreSQL is not a transactional database. |
#3
| |||
| |||
|
|
On Wed, 25 Aug 2004, PostgreSQL Bugs List wrote: CREATE OR REPLACE FUNCTION test_tr() RETURNS numeric AS' DECLARE a numeric; b numeric; BEGIN select next_number into b from test_trans where id=1; update test_trans set next_number=next_number+1 where id=1; select next_number into a from test_trans where id=1; RETURN a ; END; ' LANGUAGE 'plpgsql' VOLATILE; What I do then. I've run two sessions. In first I've run test_trans(), then in second I've run test_trans() too. Second sessions waiting for first commit or rollback. Very good. Then I've commited first session. What I see then: First session returned value 2 - very good, but second session returned value 1 - poor, oooo poor. Why , why, why? Second session should returned value 3. What happends. In version 8.0 Beta is the same situation. Additionl info: I've must user read commited transacion isolation. Please answer for my problem. My application based on this database but this problem show everyone that PostgreSQL is not a transactional database. Actually, it shows that functions have odd behavior when locking is involved (your statement would potentially be true if you could replicate this without the functions). IIRC, there are issues currently with which rows you see in such functions unless you end up using FOR UPDATE on the selects or something of that sort. |
#4
| |||
| |||
|
|
Stephan Szabo wrote: On Wed, 25 Aug 2004, PostgreSQL Bugs List wrote: Actually, it shows that functions have odd behavior when locking is involved (your statement would potentially be true if you could replicate this without the functions). IIRC, there are issues currently with which rows you see in such functions unless you end up using FOR UPDATE on the selects or something of that sort. If the first select is a "FOR UPDATE" nothing change. For sure the last select in |
|
that function doesn't see the same row if you perform that same select after the function execution, and for sure doesn't see the same row that the update statement touch. |
#5
| |||
| |||
|
|
I believe it sees the one that was valid in the snapshot as of the beginning of the function. |
#6
| |||
| |||
|
|
Stephan Szabo <sszabo (AT) megazone (DOT) bigpanda.com> writes: I believe it sees the one that was valid in the snapshot as of the beginning of the function. Actually, the problem is that it can see *both* that row and the updated row; it's a crapshoot which one will be returned by the SELECT INTO. |
|
The reason this can happen is that we're not doing SetQuerySnapshot between commands of a plpgsql function. There is discussion going way way back about whether we shouldn't do so (see the archives). I think the major reason why we have not done it is fear of introducing non-backwards-compatible behavior. Seems like 8.0 is exactly the right version to consider doing that in. |
#7
| |||
| |||
|
|
Tom Lane wrote: Stephan Szabo <sszabo (AT) megazone (DOT) bigpanda.com> writes: I believe it sees the one that was valid in the snapshot as of the beginning of the function. Actually, the problem is that it can see *both* that row and the updated row; it's a crapshoot which one will be returned by the SELECT INTO. Confirmed, if the last select is: select count(*) into a from test where id=1; this return 2. There is a space for a new bug considering that if the table have the unique index on id that select must return 1. The reason this can happen is that we're not doing SetQuerySnapshot between commands of a plpgsql function. There is discussion going way way back about whether we shouldn't do so (see the archives). I think the major reason why we have not done it is fear of introducing non-backwards-compatible behavior. Seems like 8.0 is exactly the right version to consider doing that in. If my 2 cents are valid I agree with you, what I don't totally agree is why consider this bug as a *feature* in previous 8.0 version. I don't think this was ever considered a feature (at least I never found |
#8
| |||
| |||
|
|
On Thu, 2004-08-26 at 04:23, Gaetano Mendola wrote: Tom Lane wrote: Stephan Szabo <sszabo (AT) megazone (DOT) bigpanda.com> writes: I believe it sees the one that was valid in the snapshot as of the beginning of the function. Actually, the problem is that it can see *both* that row and the updated row; it's a crapshoot which one will be returned by the SELECT INTO. Confirmed, if the last select is: select count(*) into a from test where id=1; this return 2. There is a space for a new bug considering that if the table have the unique index on id that select must return 1. The reason this can happen is that we're not doing SetQuerySnapshot between commands of a plpgsql function. There is discussion going way way back about whether we shouldn't do so (see the archives). I think the major reason why we have not done it is fear of introducing non-backwards-compatible behavior. Seems like 8.0 is exactly the right version to consider doing that in. If my 2 cents are valid I agree with you, what I don't totally agree is why consider this bug as a *feature* in previous 8.0 version. I don't think this was ever considered a feature (at least I never found any evidence of that) but more the concern was that it was "expected behavior" and changing that behavior might toss people into a loop who were expecting it. |
#9
| |||
| |||
|
|
Robert Treat wrote: On Thu, 2004-08-26 at 04:23, Gaetano Mendola wrote: Tom Lane wrote: Stephan Szabo <sszabo (AT) megazone (DOT) bigpanda.com> writes: I believe it sees the one that was valid in the snapshot as of the beginning of the function. Actually, the problem is that it can see *both* that row and the updated row; it's a crapshoot which one will be returned by the SELECT INTO. Confirmed, if the last select is: select count(*) into a from test where id=1; this return 2. There is a space for a new bug considering that if the table have the unique index on id that select must return 1. The reason this can happen is that we're not doing SetQuerySnapshot between commands of a plpgsql function. There is discussion going way way back about whether we shouldn't do so (see the archives). I think the major reason why we have not done it is fear of introducing non-backwards-compatible behavior. Seems like 8.0 is exactly the right version to consider doing that in. If my 2 cents are valid I agree with you, what I don't totally agree is why consider this bug as a *feature* in previous 8.0 version. I don't think this was ever considered a feature (at least I never found any evidence of that) but more the concern was that it was "expected behavior" and changing that behavior might toss people into a loop who were expecting it. Yes, I used the wrong expression is not a feature but a gotcha. I fairly trust that someone is currently using this behaviour considering it the good expected one. |
#10
| |||
| |||
|
|
On Thu, 2004-08-26 at 09:08, Gaetano Mendola wrote: Robert Treat wrote: On Thu, 2004-08-26 at 04:23, Gaetano Mendola wrote: Tom Lane wrote: Stephan Szabo <sszabo (AT) megazone (DOT) bigpanda.com> writes: I believe it sees the one that was valid in the snapshot as of the beginning of the function. Actually, the problem is that it can see *both* that row and the updated row; it's a crapshoot which one will be returned by the SELECT INTO. Confirmed, if the last select is: select count(*) into a from test where id=1; this return 2. There is a space for a new bug considering that if the table have the unique index on id that select must return 1. The reason this can happen is that we're not doing SetQuerySnapshot between commands of a plpgsql function. There is discussion going way way back about whether we shouldn't do so (see the archives). I think the major reason why we have not done it is fear of introducing non-backwards-compatible behavior. Seems like 8.0 is exactly the right version to consider doing that in. If my 2 cents are valid I agree with you, what I don't totally agree is why consider this bug as a *feature* in previous 8.0 version. I don't think this was ever considered a feature (at least I never found any evidence of that) but more the concern was that it was "expected behavior" and changing that behavior might toss people into a loop who were expecting it. Yes, I used the wrong expression is not a feature but a gotcha. I fairly trust that someone is currently using this behaviour considering it the good expected one. Really? I don't. I do suspect there are people using this behavior considering it the bad, but expected, one. However if people really do want this functionality to stay the same, let them speak up via a vote on the subject. |
![]() |
| Thread Tools | |
| Display Modes | |
| |