После выполнения оператора 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;
/