Есть ли способ выбрать строки в Postgresql, которые не заблокированы? У меня есть многопоточное приложение, которое будет делать:
Select... order by id desc limit 1 for update
на столе.
Если несколько потоков запускают этот запрос, они оба пытаются отбросить ту же строку.
Один получает блокировку строк, другие блоки и затем сбой после первого обновления строки. Мне бы очень хотелось, чтобы второй поток получил первую строку, которая соответствует предложению WHERE
и еще не заблокирована.
Чтобы уточнить, я хочу, чтобы каждый поток сразу обновлял первую доступную строку после выбора.
Итак, если есть строки с ID: 1,2,3,4
, первый поток будет включен, выберите строку с ID=4
и немедленно обновите ее.
Если во время этой транзакции приходит второй поток, я бы хотел, чтобы он получил строку с ID=3
и сразу же обновил эту строку.
Для Share это не будет выполнено ни с nowait
, поскольку предложение WHERE
будет соответствовать заблокированной строке (ID=4 in my example)
. В основном, что я хотел бы, это что-то вроде "AND NOT LOCKED" в предложении WHERE
.
Users
-----------------------------------------
ID | Name | flags
-----------------------------------------
1 | bob | 0
2 | fred | 1
3 | tom | 0
4 | ed | 0
Если запрос "Select ID from users where flags = 0 order by ID desc limit 1
", и когда строка возвращается, следующая вещь - "Update Users set flags = 1 where ID = 0
", тогда я хотел бы, чтобы первый поток в захвате строки с ID 4
, а следующий в возьмите строку с ID 3
.
Если я добавлю "For Update
" к выбору, то первый поток получает строку, второй блокирует и затем ничего не возвращает, потому что, как только первая транзакция совершает предложение WHERE
, больше не выполняется.
Если я не использую "For Update
", тогда мне нужно добавить предложение WHERE для последующего обновления (WHERE flags = 0), поэтому только один поток может обновить строку.
Второй поток выберет ту же строку, что и первая, но второе обновление потока завершится неудачно.
В любом случае второй поток не может получить строку и обновление, потому что я не могу заставить базу данных дать строку 4 первому потоку и строке 3 ко второму потоку транзакций перекрываться.