Механизм вставки базы данных - PullRequest
4 голосов
/ 12 февраля 2012

У меня есть вопрос о механизме вставки в разные базы данных. Предположим, что таблица с первичным ключом из одного столбца, который создается автоматически (например, столбцы идентификаторов), заблокирует ли всю таблицу при вставке новой записи? и если вставка занимает слишком много времени, другие транзакции должны ждать больше?

Ответы [ 3 ]

3 голосов
/ 13 февраля 2012

Ваш вопрос относится к любому случаю, когда вы вставляете в таблицу любое уникальное ограничение.Если индекса нет, и вы вставляете строку в таблицу, вы ожидаете, что базе данных потребуется заблокировать всю таблицу - в противном случае дубликаты могут быть вставлены в многопользовательскую систему.

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

(Но теперь вы можете спросить, что если сеанс вставляет значение, но не 'принять сразу? Что если другой сеанс попытается вставить то же значение? Ответ: второй сеанс будет ждать. Это потому, что он запросит блокировку для того же блока индекса, но так как первый сеанс еще не зафиксирован, блок все еще будет заблокирован. Он должен ждать, потому что он не может знать, будет ли первый сеанс зафиксирован или откат.)

3 голосов
/ 13 февраля 2012

По умолчанию Oracle использует уровень строки блокировки.

Эти блокировки блокируются только для писателей (обновление, удаление, вставка и т. Д.). Это означает, что select будет работать все время, когда таблица сильно обновляется, удаляется и т. Д.

Например, пусть будет таблицей A (номер col1, номер col2) с этими данными внутри:

col1  |  col2
1     |  10
2     |  20
3     |  30

Если пользователь Джон выдает по номеру time1:

update tableA set col2=11 where col1=1;

заблокирует строку 1.

В time2 пользователь Марк выдает

update tableA set col2=22 where col1=2;

обновление будет работать, потому что строка 2 не заблокирована.

Теперь таблица выглядит в базе данных:

col1  |  col2
1     |  11   --locked by john
2     |  22   --locked by mark  
3     |  30

Для Марка есть таблица (он не видит внесенных изменений)

col1  |  col2
1     |  10   
2     |  22   
3     |  30

Для Джона таблица такова: (он не видит внесенных изменений)

col1  |  col2
1     |  11   
2     |  20   
3     |  30

Если пометка пытается на time3:

update tableA set col2=12 where col1=1;

его сеанс будет зависать до time4, пока Джон не выдаст commit. (Откат также разблокирует строки, но изменения будут потеряны)

таблица (в дБ, на time4):

col1  |  col2
1     |  11   
2     |  22   --locked by mark  
3     |  30

Немедленно, после коммита Джона, row1 разблокируется, и обновление меток выполнит работу:

col1  |  col2
1     |  12   --locked by mark  
2     |  22   --locked by mark  
3     |  30

Отметим, что выпустить роллбак в момент времени 5:

col1  |  col2
1     |  11   
2     |  20   
3     |  30

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

EDIT : как объяснил Джеффри Кемп, когда у вас есть PK (он реализован в Oracle с уникальным индексом), если пользователи попытаются вставить одно и то же значение (поэтому у нас будет дубликат) блокировка произойдет в индексе . Второй сеанс будет заблокирован до окончания первого сеанса, потому что он пытается записать в том же месте. Если первый сеанс фиксируется, второй сгенерирует исключение Первичный ключ нарушен и не сможет изменить базу данных. Если первый сеанс выполняет откат, второй завершится успешно (если не возникло никаких других проблем).

(Примечание: в этом объяснении пользователя John я имею в виду сеанс, начатый пользователем John.)

3 голосов
/ 12 февраля 2012

Вставка не заблокирует таблицу.Вставленные записи не будут видны другим сеансам, пока вы не подтвердите.

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