После выполнения инструкции UPDATE эффекты инструкции станут видимыми для остальной части транзакции (и если вы передадите ее другим транзакциям). В каком порядке Oracle физически это сделает, это деталь реализации (аналогично, как порядок результата SELECT не гарантируется , если только не указывается ORDER BY).
В большинстве случаев этот заказ не имеет значения для клиента. В одном случае, когда это возможно, следует избегать взаимоблокировок с другой транзакцией, которая обновляет перекрывающийся набор строк. UPDATE блокирует обновляемую строку до конца транзакции, поэтому, если две транзакции попытаются заблокировать одни и те же строки, но в другом порядке может возникнуть взаимоблокировка.
Стандартный способ избежать взаимоблокировок - всегда фиксировать в определенном порядке. К сожалению, UPDATE не имеет предложения ORDER BY, но вы можете сделать это:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT ... WHERE condition ORDER BY ... FOR UPDATE;
UPDATE ... WHERE condition;
COMMIT;
Где condition
одинакова для обоих заявлений. Сериализуемый уровень изоляции необходим для WHERE
, чтобы всегда видеть один и тот же набор строк в обоих операторах.
Или в PL/SQL вы могли бы сделать что-то вроде этого:
DECLARE
CURSOR CUR IS SELECT * FROM YOUR_TABLE WHERE condition ORDER BY ... FOR UPDATE;
BEGIN
FOR LOCKED_ROW IN CUR LOOP
UPDATE YOUR_TABLE SET ... WHERE CURRENT OF CUR;
END LOOP;
END;
/
Логически, они происходят одновременно. На практике они этого не делают, но вы не сможете определить разницу. Это становится более интересным, если вы делаете 'UPDATE Table1 SET Index = Index + 1 WHERE Index BETWEEN 1 AND 5'. –