Am 13.09.2013 um 18:47 schrieb David Noel <david.i.n...@gmail.com>:

>> ...have you used the "for update" clause in your select statements?
> 
> Hi Ralf, thanks for the reply. I was unaware of the "for update"
> construct. Thank you!
> 
>> My understanding is, that "for update" does what you need.
> 
[...]
> My question is: according to the documentation, it seems
> that SELECT FOR UPDATE may still run into the same concurrency issue.
> If two concurrent transactions select the same row, the first will be
> given the lock. The second transaction will encounter the lock and be
> forced to wait. The update from the first transaction will occur, the
> lock will be released, and control will be passed to the second
> transaction. According to the documentation, the row will already have
> been selected, so the transaction, it seems, will continue processing
> the row as if it were marked "Inactive". In essence, the way I read
> it, it won't care that the row had been updated by the first
> transaction, and so essentially I will be running into the same
> problem I'm facing now. Am I reading this correctly?

No, I think it will work. The part "and will then lock and return the updated 
row" does not mean, that the select criteria is not rechecked.

Let's try it. Two clients:

-- > Client 1

locktest=# create table locktest (id serial primary key, state int2);
CREATE TABLE
locktest=# insert into locktest values (1, 0), (2, 0);
INSERT 0 2
locktest=# select * from locktest;
 id | state 
----+-------
  1 |      0
  2 |      0
(2 rows)

locktest=# begin;
BEGIN
locktest=# select * from locktest where state = 0 limit 1 for update;
 id | state 
----+-------
  1 |     0
(1 row)

-------------- WAIT HERE IN CLIENT 1

-- > Client 2

locktest=# begin;
BEGIN
locktest=# select * from locktest where state = 0 limit 1 for update;

------------- Client 2 waits for a lock

-- > Client 1

locktest=# update locktest set state = 1 where id = 1;
UPDATE 1
locktest=# commit;
COMMIT

-- > Client 2

 id | state 
----+-------
  2 |     0
(1 row)

[...]

You only have to take care, that the UPDATE really only updates the selected 
row.
An URL as a primary key might work, but might not be the best choice.


Ralf



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

Reply via email to