предисловие
Ранее я анализировал проблему взаимоблокировки и обнаружил, что мое понимание уровней изоляции базы данных недостаточно ясно, поэтому я воспользовался этими несколькими днями отпуска, чтобы разобраться в знаниях о четырех основных уровнях изоляции транзакций MySQL, надеясь помочь всем~
дела
Что такое транзакция?
Транзакция, состоящая из ограниченной последовательности операций с базой данных, все из которых выполняются или не выполняются ни разу, является неделимой единицей работы.
Если A переводит 100 юаней B, сначала вычтите 100 юаней со счета A, а затем добавьте 100 юаней на счет B. Если после вычета 100 юаней А, прежде чем добавить их к Б, банковская система ненормальна, и, наконец, баланс А уменьшается, но баланс Б не увеличивается. Итак, транзакция необходима, чтобы откатить деньги А, это так просто.
Четыре характеристики транзакций
- Атомарность:Транзакция выполняется как единое целое, и либо все операции над базой данных, содержащиеся в ней, либо ни одна из них не выполняются.
- последовательность:Это означает, что данные не будут уничтожены до начала транзакции и после ее завершения.Если счет А переводит 10 юаней на счет Б, общая сумма А и Б останется неизменной независимо от того, успешна она или нет.
- Изоляция:При одновременном доступе нескольких транзакций транзакции изолированы друг от друга, одна транзакция не должна мешать другим транзакциям, а несколько одновременных транзакций должны быть изолированы друг от друга. .
- Упорство:Указывает, что после фиксации транзакции операционные изменения, внесенные транзакцией в базу данных, будут сохранены в базе данных.
Проблемы параллелизма транзакций
В чем проблема с параллельным выполнением транзакций, другими словами, как одна транзакция мешает другим транзакциям? Давайте посмотрим пример~
Допустим теперь есть таблицы:
CREATE TABLE `account` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`balance` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `un_name_idx` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
В таблице есть данные:
грязное чтение
Предположим, что теперь есть две транзакции A, B:
- Теперь предположим, что баланс А равен 100, и транзакция А готовится запросить баланс Джея.
- В это время транзакция B сначала вычитает баланс Джея и вычитает 10
- Последнее чтение A - это вычтенный баланс
Как видно из приведенного выше рисунка, транзакции A и B выполняются попеременно, а транзакция A нарушается транзакцией B, поскольку транзакция A считывает незафиксированные данные транзакции B, т.е.грязное чтение.
неповторимое чтение
Предположим, что теперь есть две транзакции A и B:
- Транзакция A сначала запрашивает баланс Джея, и результат равен 100.
- В это время транзакция B вычитает баланс счета Джея, вычитает 10 и отправляет транзакцию.
- Транзакция А пошла проверить баланс счета Джея и обнаружила, что он стал равным 90.
Транзакция A снова нарушена транзакцией B! В рамках транзакции A два идентичных запроса читают одну и ту же запись, но возвращают разные данные, т.е.неповторяемое чтение.
галлюцинации
Предположим, что теперь есть две транзакции A, B:
- Транзакция A сначала запрашивает запись учетной записи с идентификатором больше 2 и получает две записи с идентификатором записи = 2 и идентификатором = 3.
- В это время открывается транзакция B, вставляется запись с id=4 и фиксируется.
- Транзакция A снова выполняет тот же запрос, но получает 3 записи с id=2,3,4.
Транзакция A запрашивает диапазон наборов результатов, другая параллельная транзакция B вставляет/удаляет данные в этот диапазон и автоматически фиксирует, а затем транзакция A снова запрашивает тот же диапазон, и наборы результатов, полученные двумя чтениями, различаются.галлюцинации.
Практика четырех уровней изоляции транзакций
Поскольку существуют параллельные транзакцииГрязные чтения, неповторяющиеся, фантомные чтенияИ другие вопросы, какие уровни изоляции транзакций реализует InnoDB?
- Читать незафиксированные
- Чтение зафиксировано
- Повторяемое чтение
- Сериализуемый
Читать незафиксированные
Лучший способ усвоить знание — это практиковать его. Хорошо, давайте перейдем к базе данных и настроим ее.читать незафиксированныеУровень изоляции, потренируйся~
Сначала установите уровень изоляции транзакции для чтения незафиксированных, откройте транзакцию A и запросите данные с идентификатором = 1.
set session transaction isolation level read uncommitted;
begin;
select * from account where id =1;
Результат выглядит следующим образом:
В это время откройте другое окно, чтобы открыть mysql, также установите текущий уровень изоляции транзакции для чтения незафиксированных, откройте транзакцию B и выполните операцию обновления.set session transaction isolation level read uncommitted;
begin;
update account set balance=balance+20 where id =1;
Затем вернитесь в окно транзакции А, а затем проверьте данные таблицы счета id = 1. Результаты следующие:
можно найти вЧитать незафиксированныеНа уровне изоляции транзакция будет читать незафиксированные данные других транзакций, то есть она существует.грязное чтениепроблема. Транзакция B еще не зафиксировалась в базе данных, но транзакция A прочитала ее, и кажется, что все перепуталось. . . На самом деле чтение незафиксированных данных — это самый низкий уровень изоляции.
ПРОЧИТАТЬ СОВЕРШЕНО
Во избежание грязных чтений в базе данных есть соотношениечитать незафиксированныеболее высокий уровень изоляции, т.е.Чтение зафиксировано.
Установите текущий уровень изоляции транзакции на READ COMMITTED, откройте транзакцию A и запросите данные с идентификатором = 1 в учетной записи.
set session transaction isolation level read committed;
begin;
select * from account where id =1;
Откройте другое окно, чтобы открыть mysql, также установите уровень изоляции транзакций для чтения зафиксированных, откройте транзакцию B и выполните следующие операции.
set session transaction isolation level read committed;
begin;
update account set balance=balance+20 where id =1;
Затем вернитесь в окно транзакции А, еще раз проверьте данные счета и обнаружите, что данные не изменились:
Затем мы переходим в окно транзакции B, чтобы выполнить операцию фиксации:
commit;
Наконец, вернитесь к окну транзакции A для запроса и обнаружите, что данные изменились:
Отсюда можно сделать вывод, что уровень изоляции установлен наПРОЧИТАТЬ СОВЕРШЕНО, проблема грязного чтения больше не возникает, и текущая транзакция может только считывать данные, отправленные другими транзакциями. Однако, если вы думаете об этом с точки зрения транзакции А, есть ли другие проблемы?
В чем проблема с уровнем изоляции чтения фиксации?
В той же транзакции A один и тот же запрос sql читает одну и ту же запись (id = 1), а результаты чтения разные, то естьнеповторяемое чтение. Поэтому, когда уровень изоляции установлен на зафиксированное чтение, все равно будетнеповторяемое чтениепроблемы параллелизма.
Повторяемое чтение
Что, если ваш начальник требует, чтобы в одной и той же транзакции результаты запроса были непротиворечивыми, то есть начальник требует, чтобы вы решили проблему неповторяющегося параллелизма? Босс, а наложница не может это сделать? практиковатьсяПовторяемое чтениеЭтот уровень изоляции
Ха-ха, результаты запросов шагов 1, 2 и 6 одинаковы, то естьПовторяющееся чтение решает проблему неповторяемого чтения"Ты доволен? Наконец-то проблема босса решена~
Решает ли уровень RR проблему фантомного чтения?
Давайте рассмотрим актуальную тему в Интернете: решается ли проблема фантомного чтения на уровне RR? Давай попрактикуемся:
Как видно из рисунка, набор результатов запроса на шагах 2 и 6 не изменился.Похоже, уровень RR решил проблему фантомного чтения~ но,Это явление все еще существует на уровне RR.:Фактически, на приведенном выше рисунке, если транзакция A не имеетupdate account set balance=200 where id=5;
этот шаг,select * from account where id>2
Запрошенный набор результатов действительно не изменился, в этом случае нетгаллюцинациипроблема. Однако при операции обновления та же транзакция, тот же sql, найденный набор результатов отличается, это соответствуетгаллюцинацииОпределение ~
Этот вопрос, дорогой друг, вы думаете, что это проблема фантомного чтения?
Сериализуемый
Первые три уровня изоляции базы данных имеют определенные проблемы с параллелизмом.Теперь давайте расширим и попрактикуем уровень изоляции SERIALIZABLE.
Установите уровень изоляции транзакции Serializable, откройте транзакцию A и запросите данные таблицы учетных записей.
set session transaction isolation level serializable;
select @@tx_isolation;
begin;
select * from account;
Откройте другое окно, чтобы открыть mysql, также установите уровень изоляции транзакций на Serializable, откройте транзакцию B и выполните вставку части данных:
set session transaction isolation level serializable;
select @@tx_isolation;
begin;
insert into account(id,name,balance) value(6,'Li',100);
Результат выполнения следующий:
Как видно из рисунка, когда уровень изоляции базы данных установлен как сериализуемый, операция записи транзакции B в таблицу ожидает операции чтения транзакции A. На самом деле, это самый строгий уровень изоляции, и операции чтения и записи не могут выполняться одновременно. Это гарантирует наилучшую безопасность, но проблема с производительностью ~
Принцип реализации уровня изоляции MySql
Существует два основных способа реализации механизма изоляции:
- Блокировка чтения-записи
- Согласованное чтение моментальных снимков или MVCC
MySql использует другую стратегию блокировки/MVCC для достижения четырех различных уровней изоляции. Принципы реализации RR и RC относятся к MVCC, а RU и Serializable — к блокировкам.
Читать незафиксированные
Официальное заявление:
SELECT statements are performed in a nonlocking fashion, but a possible earlier version of a row might be used. Thus, using this isolation level, such reads are not consistent.
Read uncommitted, принимает принцип чтения без блокировки.
- Чтение транзакции не блокируется и не блокирует чтение и запись других транзакций.
- Запись транзакции блокирует запись других транзакций, но не блокирует чтение других транзакций;
Сериализуемый
Официальное заявление:
InnoDB implicitly converts all plain SELECT statements to SELECT ... FOR SHARE if autocommit is disabled. If autocommit is enabled, the SELECT is its own transaction. It therefore is known to be read only and can be serialized if performed as a consistent (nonlocking) read and need not block for other transactions. (To force a plain SELECT to block if other transactions have modified the selected rows, disable autocommit.)
- Все операторы SELECT неявно преобразуются в
SELECT ... FOR SHARE
, то есть добавить общую блокировку. - Чтение плюс общая блокировка, запись плюс эксклюзивная блокировка, чтение и запись взаимного исключения. Если некоторые строки изменяются незафиксированными транзакциями, все операторы, выбирающие эти строки, будут заблокированы.
Принцип реализации MVCC
MVCC, называемый по-китайскиМноговерсионный контроль параллелизма, который представляет собой механизм уменьшения количества конфликтов одновременных транзакций и повышения производительности за счет чтения исторических версий данных. Его реализация зависит отНеявные поля, журнал отмен, чтение моментального снимка и текущее чтение, просмотр чтения, поэтому давайте сначала разберемся с этими точками знаний.
неявное поле
Для механизма хранения InnoDB каждая строка имеет два скрытых столбца.DB_TRX_ID, DB_ROLL_PTR, если в таблице нет первичного ключа и уникального ключа, отличного от NULL, также будет третий скрытый столбец первичного ключаDB_ROW_ID.
- DB_TRX_ID, в который записывается идентификатор транзакции последней модификации (модификации/обновления) каждой строки, размером 6 байт;
- DB_ROLL_PTR, этот скрытый столбец эквивалентен указателю, указывающему на журнал отмены сегмента отката, размером 7 байт;
- DB_ROW_ID, монотонно увеличивающийся идентификатор строки размером 6 байт;
журнал отмены
- Когда транзакция не зафиксирована, образ измененных данных (старая версия до модификации) сохраняется в журнале отмен. Чтобы восстановить данные старой версии при откате транзакции, можно отменить влияние незафиксированных данных транзакции на базу данных.
- Журнал отмены является логическим журналом. Можно считать, что при удалении записи в журнал отмен будет записана соответствующая запись вставки, а при обновлении записи будет записана соответствующая противоположная запись обновления.
- Место, где хранится журнал отмены,сегмент отката.
Когда несколько транзакций обрабатывают строку данных параллельно, модификация строки данных разными транзакциями создаст несколько версий, а затем соединит одну строку через указатель отката (DB_ROLL_PTR).Отменить цепочку журналов.
Давайте посмотрим на это на примере ~
mysql> select * from account ;
+----+------+---------+
| id | name | balance |
+----+------+---------+
| 1 | Jay | 100 |
+----+------+---------+
1 row in set (0.00 sec)
- Предположим, что в таблице accout теперь есть только одна запись, и идентификатор транзакции, вставленный в эту запись, равен 100.
- Если транзакция B (идентификатор транзакции 200), обновите запись строки с id=1 и измените значение баланса на 90.
После модификации транзакции BОтменить цепочку журналовследующее:
Чтение моментального снимка и текущее чтение
Снимок читается:
Чтение — это видимая версия данных записи (есть старая версия), без блокировки, обычные операторы select — это чтение моментальных снимков, например:
select * from account where id>2;
Текущее чтение:
Чтение — это последняя версия записанных данных, а блокировки отображаются как текущее чтение.
select * from account where id>2 lock in share mode;
select * from account where id>2 for update;
Read View
- Read View — это выполнение транзакцииСнимок прочитан, результирующее представление для чтения.
- Когда транзакция выполняет чтение снимка, создается текущий снимок системы базы данных, который записывает активные транзакции чтения и записи в текущей системе и помещает их в список.
- Представление для чтения в основном используется для оценки видимости, то есть для определения того, какая версия данных видна для текущей транзакции~
Чтобы облегчить обсуждение правил видимости для чтения ниже, сначала определите несколько переменных.
- m_ids: идентификаторы активных транзакций чтения и записи в текущей системе, ее структура данных представляет собой список.
- min_limit_id: наименьший идентификатор транзакции в списке транзакций m_ids.
- max_limit_id: список транзакций m_ids, наибольший идентификатор транзакции
- Если DB_TRX_ID
- Если DB_TRX_ID > самого большого идентификатора транзакции в списке m_ids, это указывает на то, что транзакция, создающая эту версию, создается после создания ReadView, поэтому эта версия не может быть доступна для текущей транзакции.
- Если min_limit_id =
Внимание! !Самая большая разница между уровнями изоляции RR и RC заключается в следующем:RC генерирует ReadView каждый раз перед чтением данных, в то время как RR генерирует ReadView только при первом чтении данных..
READ COMMITTED Процесс анализа неповторяющихся проблем чтения
Я думаю, что лучший способ понять новую точку знаний — этоЖивите в текущей проблеме/явлении и анализируйте ееПлюсы и минусы ~ Реализация RC также связана с MVCC.RC имеет проблемы с повторным чтением и параллелизмом, поэтому давайте проанализируем волну RC, сначала посмотрим на процесс выполнения
Предполагая, что в настоящее время в системе есть две транзакции A и B, идентификаторы транзакций равны 100 и 200 соответственно, а при существующих старых данных идентификатор вставленной транзакции равен 50~.Транзакция A сначала выполняет операцию запроса 1
# 事务A,Transaction ID 100
begin ;
查询1:select * from account WHERE id = 1;
Транзакция B выполняет операцию обновления, и цепочка журналов отмены, записанная с идентификатором = 1, выглядит следующим образом.
begin;
update account set balance =balance+20 where id =1;
Вернитесь к транзакции A и выполните операцию запроса 2.
begin ;
查询1:select * from account WHERE id = 1;
查询2:select * from account WHERE id = 1;
Запрос 2 выполняет анализ:
- Когда транзакция A выполняет оператор SELECT, она заново создает ReadView.Поскольку транзакция B (200) активна, содержимое списка m_ids ReadView равно [200]
- Из цепочки журналов отмены на приведенном выше рисунке баланс последней версии равен 1000, а ее идентификатор транзакции — 200, который находится в списке активных транзакций, поэтому текущая транзакция (транзакция A) не видна.
- Продолжаем искать следующую версию, баланс 100, идентификатор транзакции 50, что меньше минимальной записи 200 в списке активных идентификаторов транзакций, поэтому эта версия видна, поэтому результат запроса 2 будет вернуть баланс записи=100~~
Возвращаемся к транзакции B и выполняем операцию фиксации, при этом цепочка журналов отмены остается неизменной.
begin;
update account set balance =balance+20 where id =1;
commit
Снова вернитесь к транзакции A и выполните операцию запроса 3.
begin ;
查询1:select * from account WHERE id = 1;
查询2:select * from account WHERE id = 1;
查询3:select * from account WHERE id = 1;
Запрос 3 выполняет анализ:
- Когда транзакция A выполняет оператор SELECT, она заново создает ReadView.Поскольку транзакция B (200) была отправлена и не активна, список m_ids ReadView пуст.
- Поэтому транзакция А напрямую считывает последнюю запись и считывает данные версии balance=120.
Итак, это процесс решения проблемы неповторяющегося чтения в RC~ Вы можете прочитать это несколько раз, если не понимаете~
Анализ повторяющегося чтения для решения проблемы неповторяемого чтения
Давайте еще раз проанализируем, как уровень изоляции RR решает проблему неповторяющегося параллелизма чтения~
Вы можете подумать, что пример с двумя одновременными транзакциями слишком упрощен, хорошо! Давайте сделаем что-нибудь интересное, начнем с трех вещей~
Предполагая, что в системе сейчас есть две транзакции A, B и C, идентификаторы транзакций равны 100, 200 и 300 соответственно, а идентификатор транзакции вставки биржевых данных равен 50~.# 事务A,Transaction ID 100
begin ;
UPDATE account SET balance = 1000 WHERE id = 1;
# 事务B,Transaction ID 200
begin ; //开个事务,占坑先
На данный момент в таблице учетных записей цепочка журналов отмены, записанная с id = 1, выглядит следующим образом:
# 事务C,Transaction ID 300
begin ;
//查询1:select * from account WHERE id = 1;
Анализ процесса выполнения запроса 1:
- Когда транзакция C выполняет оператор SELECT, она сначала создает ReadView. Поскольку транзакции A (100) и B (200) активны, содержимое списка m_ids ReadView равно [100, 200].
- Из цепочки журналов отмены на приведенном выше рисунке баланс последней версии равен 1000, а ее идентификатор транзакции — 100, который находится в списке активных транзакций, поэтому текущая транзакция (транзакция C) не видна.
- Продолжаем находить следующую версию, баланс 100, идентификатор транзакции 50, что меньше минимальной записи 100 в списке активных идентификаторов транзакций, поэтому эта версия видна, поэтому результат запроса 1 будет вернуть баланс записи=100~~
Далее мы отправляем транзакцию A:
# 事务A,Transaction ID 100
begin ;
UPDATE account SET balance = 1000 WHERE id = 1;
commit;
В транзакции B выполните операцию обновления и измените баланс записи с id=1 на 2000. После обновления цепочка журналов отмены выглядит следующим образом:
# 事务B,Transaction ID 200
begin ; //开个事务,占坑先
UPDATE account SET balance = 2000 WHERE id = 1;
Вернитесь к транзакции C и выполните запрос 2.
# 事务C,Transaction ID 300
begin ;
//查询1:select * from account WHERE id = 1;
//查询2:select * from account WHERE id = 1;
Запрос 2: выполнить анализ:
- На уровне RR при выполнении запроса 2, т.к.Предыдущий ReadView был сгенерирован, поэтому возьмите предыдущий ReadView напрямую, список активных транзакций [100,200].
- Из цепочки журналов отмены на приведенном выше рисунке баланс последней версии равен 2000, а ее идентификатор транзакции — 200, который находится в списке активных транзакций, поэтому текущая транзакция (транзакция C) не видна.
- Продолжаем искать следующую версию, баланс 1000, идентификатор транзакции 100, и она тоже есть в списке активных транзакций, поэтому текущая транзакция (транзакция С) не видна.
- Продолжайте искать следующую версию, баланс 100, идентификатор транзакции 50, что меньше минимальной записи 100 в списке активных идентификаторов транзакций, поэтому эта версия видна, поэтому результат запроса 2 также возвращает баланс записи=100~~
Дополнительные понятия, связанные с блокировкой (прилагаются):
Общие блокировки и эксклюзивные блокировки
InnoDB реализует стандартные блокировки на уровне строк, включая два типа: разделяемые блокировки (называемые блокировками s) и эксклюзивные блокировки (называемые блокировками x).
- Общая блокировка (S-блокировка): позволяет блокирующей транзакции читать строку.
- Эксклюзивная блокировка (блокировка X): позволяет блокирующей транзакции обновлять или удалять строку.
Если транзакция T1 удерживает блокировку s на строке r, когда другая транзакция T2 запрашивает блокировку на r, она сделает следующее:
- T2 запрашивает немедленное предоставление блокировки s, и в результате T1 и T2 удерживают блокировку s на строке r.
- Запрос T2 x блокировка не может быть предоставлена немедленно
Если T1 удерживает блокировку x для r, то запрос T2 на блокировки x и s для r не может быть разрешен немедленно, и T2 должен ждать, пока T1 освободит блокировку x, потому что блокировка X несовместима ни с какими блокировками.
Блокировка записи
- Блокировки записей — это простейшие блокировки строк.заблокировать только одну строку. как:
SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE
- блокировка записивсегда добавляется в индексДа, даже если у таблицы нет индекса, InnoDB неявно создаст индекс и будет использовать этот индекс для обеспечения блокировки записей.
- Будет блокировать другие транзакции для вставки, обновления, удаления
Запись данных транзакции блокировки (ключевые слова:lock_mode X locks rec but not gap
), записано следующим образом:
RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t`
trx id 10078 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 4; hex 8000000a; asc ;;
1: len 6; hex 00000000274f; asc 'O;;
2: len 7; hex b60000019d0110; asc ;;
Гэп-замки
- Гэп-блокировка — это блокировка, помещаемая между двумя индексами, либо перед первым индексом, либо после последнего индекса.
- Использование блокировок пробелов блокирует интервал, а не только каждую часть данных в этом интервале.
- Гэп-блокировки только предотвращают вставку других транзакций в гэп, они не мешают другим транзакциям получить гэп-блокировки на том же гэпе, так что гэп x блокировка и гэп s блокировка имеют одинаковый эффект.
Next-Key Locks
- Блокировка следующего ключа представляет собой комбинацию блокировки записи и блокировки промежутка, которая относится к блокировке, добавленной к записи, и промежутку перед этой записью.
Анализ фантомного чтения на уровне RC
Поскольку у RC есть проблема фантомного чтения, мы сначала переходим к уровню изоляции RC и анализируем волну~
Предположим, что таблица account содержит 4 элемента данных.
- Откройте транзакцию A, выполните текущее чтение и запросите все записи с id>2.
- Затем откройте транзакцию B и вставьте часть данных с id=5.
- После того, как транзакция B успешно вставит данные, она изменяет запись с id=3.
- Вернитесь к транзакции A и снова выполните текущий запрос на чтение с id>2.
- Транзакция B может вставлять данные с id=5, но не может обновлять данные с id=3 и заблокирована. Докажите, что транзакция A блокирует две записи с id = 3 и id = 4 при выполнении текущего чтения, но не блокирует диапазон id > 2~.
- После того, как транзакция B заблокирована, возникает взаимоблокировка, когда она переключается обратно на транзакцию A для выполнения текущей операции чтения. Поскольку транзакция B будет блокировать новую запись (id = 5) при вставке, транзакция A снова выполнит текущее чтение. Чтобы получить запись с id > 3, ей необходимо установить три записи с id = 3, 4 и 5. , Запись заблокирована, но запись с id = 5 заблокирована транзакцией B, поэтому транзакция A заблокирована транзакцией B, в то время как транзакция B все еще ожидает, пока транзакция A снимет блокировку с id = 3, и, наконец, возникает тупик.
Следовательно, мы можем обнаружить, что на уровне изоляции RC заблокированные операторы select, update, delete и другие используют блокировки записи, и вставка других транзакций все еще может выполняться, поэтому будут фантомные чтения~
Уровень RR разрешает анализ фантомного чтения
Поскольку RR должен решить проблему фантомного чтения, как это решить, давайте проанализируем это~
Предположим, что таблица учетных записей содержит 4 элемента данных уровня RR.
- Откройте транзакцию A, выполните текущее чтение и запросите все записи с id>2.
- Затем откройте транзакцию B и вставьте часть данных с id=5.Можно обнаружить, что когда транзакция B выполняет операцию вставки, она блокируется ~ потому что, когда транзакция A выполняет select ... lock в режиме общего доступа, она не только добавляет блокировки к 2 записям с id = 3, 4, но также блокирует id > 2 Gap-блокировки также добавляются в этот диапазон.
Следовательно, мы можем обнаружить, что на уровне изоляции RR заблокированные операторы select, update, delete и другие будут использовать блокировку промежутка + блокировку соседней клавиши, чтобы заблокировать диапазон между записями индекса и избежать вставки записей между диапазонами, чтобы избежать записи фантомной строки.
Ссылка и спасибо
- Путь к тупикам — изучите транзакции и уровни изоляции
- Пять минут, чтобы выяснить уровень изоляции транзакций MySQL
- 4 уровня изоляции транзакций, как умно реализована InnoDB?
- Уровень изоляции транзакций MySQL и MVCC
- Принцип и реализация механизма MySQL InnoDB MVCC
- Многоверсионный контроль параллелизма MVCC
Личный публичный аккаунт
- Если вы считаете, что это хорошо написано, пожалуйста, поставьте лайк + подпишитесь, спасибо~
- Если что-то не так, укажите на это, большое спасибо.
- В то же время, я очень жду, что мои друзья обратят внимание на мой официальный аккаунт, и позже я постепенно представлю более качественные галантерейные товары~ хи хи
- адрес гитхаба:GitHub.com/Я бы хотел 123/Java…