Існує немає ORDER BYв SQL UPDATEкоманді. Postgres оновлює рядки у довільному порядку:
Щоб уникнути тупикових ситуацій з абсолютною впевненістю, ви можете запускати свої висловлювання в ізоляційній послідовності угод . Але це дорожче, і вам потрібно підготуватися до повторення команд щодо відмови серіалізації.
Ваш найкращий спосіб дії - це, ймовірно, блокування явним чином SELECT ... ORDER BY ... FOR UPDATEу підзапиті або окремому SELECTу транзакції - за замовчуванням рівень ізоляції "читання здійснено". Цитуючи Тома Лейн на pgsql-загальному :
Має бути все гаразд - блокування FOR UPDATE - це завжди останній крок у трубопроводі SELECT.
Це має зробити цю роботу:
BEGIN;
SELECT 1
FROM foo
WHERE baz = 1234
ORDER BY bar
FOR UPDATE;
UPDATE foo
SET bar = bar + 1
WHERE baz = 1234;
COMMIT;
Багатоцільовий індекс на (baz, bar)може бути ідеальним для продуктивності. Але оскільки bar, очевидно, багато оновлюється , індекс з одним стовпцем на просто (baz)може бути ще кращим. Залежить від пари факторів. Скільки рядків на кожен baz? Чи можливі оновлення HOT без бездротового індексу? ...
Якщо baz оновлюється одночасно, є ще навряд чи кут випадку ймовірність конфліктів (в документації) :
Можливо, що SELECTкоманда, що працює на READ COMMITTED
рівні ізоляції транзакцій, використовує ORDER BYта блокуючий пункт, щоб повернути рядки з порядку. ...
Крім того, якщо у вас виникне унікальне обмеження bar, враховуйте DEFERRABLEобмеження, щоб уникнути унікальних порушень в межах однієї команди. Відповідна відповідь:
CREATE TABLEкод.