вопрос:
1. Какая ситуация называется фантомным чтением?
2. Можно ли предотвратить фантомное чтение при уровне изоляции повторяющегося чтения Mysql?
3. Что такое текущее чтение и что такое чтение моментального снимка?
Определение фантомного чтения:
Транзакция А считывает данные по определенным условиям, при этом транзакция Б вставляет новые данные с теми же условиями поиска, а когда транзакция А снова читает по исходным условиям, находит транзакцию Б新插入的数据 称为幻读
Если транзакция A выполняет поиск в соответствии с определенными условиями, транзакция B удаляет определенную часть данных, которая соответствует условиям, в результате чего при повторном чтении транзакцией A становится на одну единицу данных меньше. Этот случай классифицируется как неповторяющееся чтение
Готов к работе:
Уровень изоляции Mysql可重复读
;
CREATE TABLE `author` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
INSERT into author VALUES (1,'g1',20),(5,'g5',20),(15,'g15',30),(20,'g20',30);
Найдите авторов, которым исполнилось 20 лет, и измените их имена на G0.
время | Session 1 | Session2 |
---|---|---|
begin; | ||
T1 | select * from author where age = 20; Результат: (1,g1,20),(5,g5,20) |
|
T2 | INSERT into author VALUES (25,'g25',20); | |
T3 | select * from author where age = 20; Результат: (1,g1,20),(5,g5,20) |
|
T4 | update author set name = 'G0' where age = 20 Результат: количество затронутых строк отображается как 3 строки. |
|
T5 | select * from author where age = 20; Результат: (1,g0,20),(5,g0,20),(25,g0,20) |
Проанализируем следующую ситуацию:
- В T1 считываются данные возраста 20, и Session1 получает 2 записи.
- В момент времени T2 другой процесс Session2 вставил новую запись с возрастом 20 лет.
- При времени T3 Session1 считывает данные, возраст которых снова составляет 20 и обнаруживает, что есть еще 2 штуки данных.
貌似
Вновь вставленные данные Session2 не влияют на чтение транзакции Session1.
Для ситуации в момент времени Т1 -- Т3, по результатам, в
可重复度读
Кажется, это решается на уровне изоляции幻读
Проблема.
- На этапе T4 Session1 изменяет данные, возраст которых равен 20, и обнаруживает, что количество затронутых строк равно 3. Почему в T3 можно найти только 2 фрагмента данных, а сейчас изменены 3 фрагмента данных?
- На T5 сеанс 1 снова считывает данные с возрастом 20 и обнаруживает, что результат стал равным 3. Мы знаем, что третий модифицированный — это тот, который был добавлен сеансом 2 на момент времени T2.
По результатам T4 и T5 Session1 прочитал данные, недавно вставленные Session2. произведено
幻读
Феномен
В конце концов, при уровне изоляции повторяющегося чтения была ли решена проблема фантомного чтения?
Учащиеся, знакомые с MVCC, должны знать или слышать о нем.当前读
,а также快照读。
(Студенты, которые не знают, вы можете найти соответствующую информацию для понимания, конечно, в продолжении у меня будет статья, посвященная MVCC).
Первое, что нужно знать, это способность MVCC создавать моментальные снимки данных за считанные секунды в InnoDB.快照读
То есть при чтении данных данные видимой версии транзакции будут считываться по определенным правилам. а также当前读
Просто прочитайте последнюю версию данных.
При каких обстоятельствах используется чтение моментального снимка: (чтение моментального снимка, без блокировки)
Общий оператор select * from .... где ... - это прочитанный снимок
При каких обстоятельствах используется текущее чтение: (текущее чтение будет заблокировано при поиске)
select * from .... where ... for update select * from .... where ... lock in share mode update .... set .. where ... delete from. . where ..
如果事务中都使用快照读,那么就不会产生幻读现象,但是快照读和当前读混用就会产生幻读。
Если используется текущее чтение, можно ли решить проблему фантомного чтения?
Давайте сначала восстановим данные в исходное состояние
TRUNCATE TABLE author;
INSERT into author VALUES (1,'g1',20),(5,'g5',20),(15,'g15',30),(20,'g20',30);
время | Session 1 | Session2 |
---|---|---|
begin; | ||
T1 | select * from author where age = 20 for update; Результат: (1,g1,20),(5,g5,20) |
|
T2 | INSERT into author VALUES (25,'g25',20); блокировка, ожидание блокировки |
|
T3 | select * from author where age = 20 for update; Результат: (1,g1,20),(5,g5,20) |
|
Вы можете видеть, что сеанс 2 заблокирован. Необходимо дождаться, пока Session1 зафиксирует транзакцию для завершения. Когда мы используем каждое чтение в транзакции, используя当前读
, то есть вручную превращая InnoDB в串行化
. Это в определенной степени снижает параллелизм, но также позволяет избежать фантомных чтений.
Почему текущий прочитал блокировать вставку новых данных, в основном потому, что间隙锁
запорный механизм. (Mysql锁
Это тоже большая проблема, и в продолжении будет отдельная глава)
Суммировать:
- Я надеюсь, что благодаря этой статье я смогу понять определение галлюцинаций. читать другие транзакции
新插入的数据
, это явление называется фантомным чтением. - Разница между текущим чтением и чтением моментального снимка, а также знание того, когда происходит чтение моментального снимка, а когда текущее чтение.
- Под повторямым уровнем изоляции чтения только текущий чтение или только снимка можно использовать в транзакции, чтобы избежать чтения Phantom.