Есть ли способ выбрать строки в 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)
. В основном я хотел бы что-то вроде «И НЕ БЛОКИРОВАТЬ» в предложении 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 второму потоку, когда транзакции перекрываются.