В операторе обновления SQL Oracle происходит ли обновление строки одновременно? - PullRequest
7 голосов
/ 04 марта 2012

В операторе обновления SQL Oracle, если обновление затронет 5 строк, обновляет ли оператор обновления все 5 строк одновременно или последовательно?Например,

UPDATE table1 
set column2 = 'completed' WHERE
index between 1 AND 5

В вышеприведенном утверждении будет ли индекс 1-5 обновляться последовательно, то есть 1, 2, 3, 4, затем 5, или это будет происходить одновременно (1-5 все сразу).

Я ссылался на документацию Oracle , но, похоже, об этом ничего не сказано.

Ответы [ 5 ]

4 голосов
/ 04 марта 2012

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

Потенциально либо.

В этом случае, поскольку вы просто обновляете 5 строк, маловероятно, что параллельный DML будет уместным.Предполагая, что UPDATE не вызывает параллельный DML, строки будут обновляться последовательно, хотя порядок, в котором обновляются строки, является произвольным.INDEX 1 может быть первым, который будет обновлен, последним, чтобы быть обновленным, или это может быть обновлено в середине.Это зависит от плана запроса.

2 голосов
/ 04 марта 2012

UPDATE, DELETE и INSERT не имеют определенного порядка. Концептуально они относятся к набору и делаются одновременно. С практической точки зрения, не полагайтесь на последовательность, которую вы можете наблюдать - это детали реализации, которые могут измениться, и это происходит только потому, что реальный мир мешает теории.

2 голосов
/ 04 марта 2012

Ссылка, которую вы указали, действительно покрывает это Oracle всегда обеспечивает согласованность чтения на уровне инструкций - это означает, что ни один запрос к таблице 1 не вернет некоторые обновленные записи, а некоторые - нет. Это будет все или ничего и независимо от уровня изоляции.

0 голосов
/ 04 марта 2012

Все записи будут обновляться как одна запись в одной транзакции.Oracle не гарантирует какой-либо порядок в последовательности обновления.

Вы можете обновить любое поле значением dbms_transaction.local_transaction_id в вашей таблице, чтобы проверить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...