Існує немає 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
код.