05.04.2023 02:53
polin11
 
Использую СУБД PGSQL.

Нужно получить мин. значение CreateDate из таблицы документ
SQL код:
SELECT MIN("CreateDate")
FROM "Document" 
если минимальная дата < текущей в цикле вешается транзация и пересчитывается поле CreateDate, достаю записи
таким запросом:
SQL код:
SELECT *
FROM "Document"
WHERE "CreateDate" NOW()::DATE
ORDER BY 
"CreateDate"
LIMIT 10
FOR UPDATE SKIP LOCKED 
Обновление записей
SQL код:
UPDATE "Document"
SET "CreateDate" = ...
... 

Насколько понимаю логику работы SELECT FOR UPDATE SKIP LOCKED при паральленых вызовах
будут взяты не заблокированные записи.
Как понимаю проблема будет возникать при получении мин. значение CreateDate,
SQL код:
SELECT MIN("CreateDate")
FROM "Document" 
заблокированные записи будут пропущены и актуальное значение не получить.
Подскажите пож-ста, можно как-то исправить эту проблему?
05.04.2023 02:54
Капитан О.
 
Для решения этой проблемы можно использовать блокировку строки с помощью SELECT FOR UPDATE. При выполнении SELECT FOR UPDATE строки, удовлетворяющие условию, будут заблокированы для других транзакций до момента их разблокировки или завершения текущей транзакции.

Таким образом, вы можете выполнить запрос на поиск строки с наименьшим значением Cr и заблокировать ее, чтобы обновить эту строку. Вот пример запроса:

BEGIN;
SELECT Cr FROM документ FOR UPDATE WHERE дата < текущая_дата ORDER BY Cr ASC LIMIT 1;
-- выполнение другой логики или обновление записей
UPDATE документ SET Cr = новое_значение WHERE ...
COMMIT;

В этом запросе мы используем блокировку строк с помощью SELECT FOR UPDATE для нахождения строки с наименьшим значением Cr. Затем мы выполняем другую логику или обновляем записи, после чего завершаем транзакцию с помощью COMMIT.

Таким образом, вы можете гарантировать, что только одна транзакция может блокировать и обновлять строку с наименьшим значением Cr в конкретный момент времени.
05.04.2023 06:43
OlegON
 
ты написал способ решения, судя по всему неверный, но не описал цель, к которой тебя непонятно теперь как вести
зачем тебе блокировать строки, почему сразу не делать update? в большинстве случаев select for update говорит о неправильной логике программы
Часовой пояс GMT +3, время: 02:50.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.