REPEATABLE_READ
не блокирует таблицу. Это гарантирует, что транзакция увидит одни и те же строки в любой момент. Поясню на примере:
Time Transaction 1 Transaction2
1 Begin Tx 1
2 Begin Tx 2
4 Select count(*) from my_tab;
5 Select count(*) from my_tab;
6 Insert into ... my_tab;
7 Commit;
8 Select count(*) from my_tab;
9 Insert into ... my_tab;
10 Select count(*) from my_tab;
11 Commit;
12 Begin Tx3
13 Select count(*) from my_tab;
Если my_tab имеет 10 строк, то результатом подсчета будет:
- Время 4: 10 рядов
- Время 5: 10 рядов
- Время 8: 10 строк, потому что таблица находится в режиме repeateble_read, если режим транзакции read_commited, также будет 10 строк. Но если Tx установлен в read_uncommited, количество строк будет 11.
- Время 10: поскольку он находится в режиме повторного чтения, количество строк будет равно 11 (десять оригиналов плюс одна вставка в текущей транзакции). Если режим tx read_commited, количество строк будет равно 12 (десять оригиналов плюс одна вставка tx1 и одна вставка текущего tx).
- Время 13: здесь количество строк будет равно 12 для всех режимов транзакций.
В сериализуемом режиме каждая транзакция выполняется в одиночном режиме, поэтому, пока транзакция не заканчивается фиксацией или откатом, ни одна транзакция не может начаться. Если этот режим гарантирует непротиворечивость базы данных, есть серьезные проблемы с производительностью.
ИЗМЕНИТЬ
Из стандарта SQL-92 (страницы 67 и 68), размещенного на http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt (получено из Википедии):
SQL-транзакция имеет уровень изоляции READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ или SERIALIZABLE. Уровень изоляции SQL-транзакции определяет степень, в которой операции с SQL-данными или схемами в этой SQL-транзакции подвержены влиянию и могут влиять на операции с SQL-данными или схемами в параллельных SQL-транзакциях. Уровень изоляции SQL-транзакции по умолчанию SERIALIZABLE. Уровень может быть явно задан с помощью .
Выполнение параллельных SQL-транзакций на уровне изоляции SERIALIZABLE гарантированно сериализуемо. Сериализуемое выполнение определяется как выполнение операций параллельного выполнения SQL-транзакций, которое производит тот же эффект, что и некоторое последовательное выполнение тех же самых SQL-транзакций. Последовательное выполнение — это такое, при котором каждая SQL-транзакция выполняется до завершения до начала следующей SQL-транзакции.
Уровень изоляции определяет, какие явления могут возникнуть при выполнении параллельных SQL-транзакций. Возможны следующие явления:
1) P1 («грязное чтение»): SQL-транзакция T1 изменяет строку. Затем SQL-транзакция T2 считывает эту строку до того, как T1 выполнит COMMIT. Если затем T1 выполнит ROLLBACK, T2 прочитает строку, которая никогда не была зафиксирована, и поэтому ее можно считать никогда не существовавшей.
2) P2 ("Неповторяемое чтение"): SQL-транзакция T1 читает строку. Затем SQL-транзакция T2 изменяет или удаляет эту строку и выполняет COMMIT. Если затем T1 попытается перечитать строку, он может получить измененное значение или обнаружить, что строка была удалена.
3) P3 («Фантом»): SQL-транзакция T1 считывает набор строк N, удовлетворяющих некоторым . Затем SQL-транзакция T2 выполняет SQL-операторы, которые генерируют одну или несколько строк, удовлетворяющих требованиям, используемым SQL-транзакцией T1. Если затем SQL-транзакция T1 повторяет начальное чтение с тем же , она получает другой набор строк.
Четыре уровня изоляции гарантируют, что каждая SQL-транзакция будет выполнена полностью или не будет выполнена вообще, и никакие обновления не будут потеряны. Уровни изоляции различны в отношении явлений P1, P2 и P3. В таблице 9 «Уровни изоляции SQL-транзакций и три явления» указаны явления, которые возможны и невозможны для данного уровня изоляции.
Level P1 P2 P3
---------------------------------------------------------
| READ UNCOMMITTED | Possible | Possible | Possible |
---------------------------------------------------------
| READ COMMITTED | Not | | |
| | Possible | Possible | Possible |
---------------------------------------------------------
| REPEATABLE READ | Not | Not | |
| | Possible | Possible | Possible |
---------------------------------------------------------
| SERIALIZABLE | Not | Not | Not |
| | Possible | Possible | Possible |
---------------------------------------------------------------
| |
| Note: The exclusion of these phenomena or SQL-transactions |
| executing at isolation level SERIALIZABLE is a |
| consequence of the requirement that such transactions |
| consequence of the be serializable. |
---------------------------------------------------------------
ИЗМЕНИТЬ 2
Хорошо, вас интересуют блокировки и блоки, на данный момент то, как поставщики RDMS реализуют это, может различаться (например, SQL Server слишком странен), но для общей картины это может быть полезно, следующее объяснение применимо, когда вы пытаетесь изменять/читать одни и те же данные (строки). Существует два типа блокировок, когда RDMS выполняет транзакцию:
- Общие блокировки: этот тип блокировки позволяет другим транзакциям получать доступ к данным. Например, многие транзакции могут одновременно считывать одни и те же данные.
- Эксклюзивные блокировки: этот тип блокировки блокирует ресурс, избегая доступа к нему другой транзакции, например, две транзакции не могут одновременно изменять одни и те же данные, транзакция, которая пытается изменить ресурс, должна проверять, нет ли эксклюзивных блокировок. ресурс. Если на ресурсе нет монопольной блокировки, то транзакция получает монопольную блокировку, и пока она не освободит блокировку, ни одна транзакция не может получить блокировку и должна ждать освобождения монопольной блокировки.
Второй момент здесь: Что заблокировано?. Обычно существует два типа замков:
- Блокировки на уровне таблицы: когда транзакция пытается изменить данные, транзакция получает эксклюзивную блокировку всей таблицы, другие транзакции должны ждать снятия блокировок транзакцией.
- Блокировки на уровне строк: когда транзакция пытается изменить данные, транзакция получает эксклюзивные блокировки строк, участвующих в транзакции, другие транзакции, которые хотят изменить то же подмножество строк, должны ждать, пока первая транзакция не завершится.
Примечание относительно Dead Lock, представьте себе следующий сценарий:
Time Transaction 1 Transaction 2
1 Begin Tx 1
2 Begin Tx 2
4 Update table X set... where id = 5
5 Update table X set ... where id = 5;
6 Update table X set... where id = 6
7 Commit;
8 Commit;
Если база данных настроена на блокировку на уровне строк, то транзакция 2 будет ждать от времени 5 до времени 7, потому что транзакция 1 первой получает монопольную блокировку. Теперь представьте следующий пример:
Time Transaction 1 Transaction 2
1 Begin Tx 1
2 Begin Tx 2
4 Update table X set... where id = 5
5 Update table X set ... where id = 6;
6 Update table X set... where id = 6
7 Update table X set ... where id = 5;
8 Commit;
9 Commit;
Этот сценарий известен как «Мертвая блокировка», потому что во время 6 транзакция 1 будет ждать снятия блокировки, полученной транзакцией 2 во время 5, но во время 7 транзакция 2 должна ждать блокировки, полученной транзакцией 1 во времени. 4. Различные СУБД по-разному управляют тупиковой блокировкой, например, MySQL с InnoDB вызовет исключение тупиковой блокировки для транзакции 2, позволяя транзакции 1 завершиться нормально.
Есть интересные статьи:
С наилучшими пожеланиями
person
Ernesto Campohermoso
schedule
31.07.2013