Есть ли способ выбрать строки в 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 ко второму потоку транзакций перекрываться.