Oracle - Как Oracle управляет специфичными для транзакций операторами DML - PullRequest
2 голосов
/ 15 августа 2011

Представьте, что у меня есть эта простая таблица:

Table Name: Table1
Columns:    Col1 NUMBER (Primary Key)
            Col2 NUMBER

Если я вставлю запись в Таблицу1 без фиксации ...

INSERT INTO Table1 (Col1, Col2) Values (100, 1234);

Как Oracle узнает, что следующий оператор INSERT нарушает ограничение PK, поскольку в базу данных еще ничего не было добавлено.

INSERT INTO Table1 (Col1, Col2) Values (100, 5678);

Где / как Oracle управляет транзакциями, чтобы он знал, что я нарушаю ограничение, когда я еще даже не совершил транзакцию.

Ответы [ 4 ]

8 голосов
/ 15 августа 2011

Oracle создает индекс для применения ограничения первичного ключа (по умолчанию это уникальный индекс).Когда сеанс А вставляет первую строку, структура индекса обновляется, но изменение не фиксируется.Когда сеанс B пытается вставить вторую строку, операция обслуживания индекса отмечает, что в индексе уже есть ожидающая запись с этим конкретным ключом.Сеанс B не может получить защелку, которая защищает структуру общего индекса, поэтому он будет блокироваться до завершения транзакции сеанса A.В этот момент сеанс B либо сможет получить защелку и внести свои собственные изменения в индекс (потому что откат А), либо он заметит, что другая запись была зафиксирована, и выдаст уникальное нарушение ограничения (потому что зафиксированный А).

2 голосов
/ 15 августа 2011

Это из-за уникального индекса, который применяет ограничение первичного ключа. Даже если вставка в блок данных еще не зафиксирована, попытка добавить повторяющуюся запись в индекс не может быть успешной, даже если это сделано в другом сеансе.

1 голос
/ 15 августа 2011

То, что вы еще не сделали коммит, не означает, что первая запись не была отправлена ​​на сервер.Oracle уже знает о ваших намерениях вставить первую запись.Когда вы вставляете вторую запись, Oracle знает наверняка, что это никогда не будет успешным без нарушения ограничения, поэтому он отказывается.

Если другой пользователь вставит вторую запись, Oracleпримите это, если первая запись еще не была передана.Если второй пользователь совершит коммит перед вами, ваш коммит завершится неудачей.

0 голосов
/ 15 августа 2011

Если конкретное ограничение не «отложено», оно будет проверено в точке выполнения оператора.Если оно отложено, оно будет проверено в конце транзакции.Я предполагаю, что вы не откладывали свой ПЕРВИЧНЫЙ КЛЮЧ, и поэтому вы получаете нарушение даже до того, как совершите коммит.

То, как это действительно делается, является подробностью реализации и может различаться в разных системах баз данных и даже в версияхта же система.Разработчик приложения, вероятно, не должен делать слишком много предположений по этому поводу.В случае Oracle PRIMARY KEY использует базовый индекс для повышения производительности, в то время как существуют системы, которым даже не требуется индекс (если вы можете жить с соответствующим падением производительности).

Кстати, отсроченный OracleОграничение PRIMARY KEY основано на неуникальном индексе (по сравнению с неотложным PRIMARY KEY, который использует уникальный индекс).

--- EDIT ---

Я только что понял, что вы этого не сделалидаже совершить первую вставку.Я думаю, что ответ Джастина хорошо объясняет, как то, что по сути является конфликтом блокировки, приводит к остановке одной из транзакций.

...