Re: Serialization, Locking...implement processing Queue with a table

Поиск
Список
Период
Сортировка
От Manfred Koizar
Тема Re: Serialization, Locking...implement processing Queue with a table
Дата
Msg-id kap3cv0nogppe1g3a021ghkgjojvlgkf4u@4ax.com
обсуждение исходный текст
Ответ на Re: Serialization, Locking...implement processing Queue with a table  ("D. Dante Lorenso" <dante@lorenso.com>)
Список pgsql-general
On Wed, 14 May 2003 01:10:39 -0500, "D. Dante Lorenso"
<dante@lorenso.com> wrote:
>> How do you distinguish between (i) and (ii)?  Just do
>> SELECT job_id FROM job_table
>>     WHERE processor_id = 0 LIMIT 1;
>> If this returns 0 rows, you have (i).
>> If it returns one row, you have (ii).
>
>You can't do it this way

Oh.

> because if this select IS successful,
>you'll still need to LOCK the row for the update.

That's exactly the reason why I told you ...

|(ii)  The row has been reserved by another transaction running at the
|same time.  In this case, restart at SELECT FOR UPDATE.
                                   ^^
                                 not after!

If there is a row satisfying the WHERE clause but SELECT FOR UPDATE
does not return it, this is the effect of a race condition:

SELECT xmax,* FROM job;
 xmax | id | pr
------+----+----
    0 |  2 |  0
    0 |  3 |  1
    0 |  1 |  2
    0 |  4 |  0

Session 1                    Session 2

BEGIN;
SELECT xmax,* FROM job
 WHERE pr = 0 FOR UPDATE LIMIT 1;
 xmax | id | pr
------+----+----
    0 |  2 |  0
(1 row)

select xmax,* FROM job
 WHERE id = 2;
  xmax | id | pr
-------+----+----
 58634 |  2 |  0
(1 row)
                             BEGIN;
                             select xmax,* FROM job
                              WHERE pr = 0 LIMIT 1;
                              xmax  | id | pr
                             -------+----+----
                              58634 |  2 |  0
                             (1 row)

                             SELECT xmax,* FROM job
                              WHERE pr = 0 FOR UPDATE LIMIT 1;
                             -- waits, because the row with id=2
                             -- satisfies the WHERE clause but
                             -- is locked by transaction 58634 ...
UPDATE job SET pr = 1
 WHERE id = 2;
                             -- The same would happen, if we did the
                             -- SELECT FOR UPDATE here (after the
                             -- UPDATE in the other session), because
                             -- our *visible* version of the row
                             -- still satisfies the WHERE clause.

select xmax,* FROM job
 WHERE id = 2;
 xmax | id | pr
------+----+----
    0 |  2 |  1
(1 row)
-- xmax = 0 because we see
-- the newly inserted tuple

COMMIT;
                             -- continues ...
                              xmax | id | pr
                             ------+----+----
                             (0 rows)
                             -- because the row this SELECT was about
                             -- to return does not satisfy pr = 0
                             -- any more

                             SELECT xmax,* FROM job
                              WHERE pr = 0 LIMIT 1;
                              xmax | id | pr
                             ------+----+----
                                 0 |  4 |  0
                             (1 row)
                             -- but there is another row, so ...

                             SELECT xmax,* FROM job
                              WHERE pr = 0 FOR UPDATE LIMIT 1;
                              xmax | id | pr
                             ------+----+----
                                 0 |  4 |  0
                             (1 row)
                             -- does not necessarily return the same
                             -- id as the previous SELECT

                             UPDATE ...;
                             COMMIT;

HTH.
Servus
 Manfred

В списке pgsql-general по дате отправления:

Предыдущее
От: James Gregory
Дата:
Сообщение: server process segfaulting
Следующее
От: Bruno Wolff III
Дата:
Сообщение: Re: executables when upgrading