Кто-бы ни купил MySQL, она еще долго будет будоражить ресурсы Наших с Вами серверов — и это хорошо.

Есть таблица 

CREATE TABLE test (id INT, value VARCHAR(255)) ENGINE=InnoDB;

Что по Вашему покажет этот запрос?

START TRANSACTION;
INSERT INTO test(id, value) VALUES (1, 'test'), (2, 'test 2');
SELECT * FROM test;
COMMIT;
SELECT * FROM test;

А что покажет простейший SELECT во время выполнения текущей транзакции? Не ясно. Вот и придумали такие правила.

Первый READ UNCOMMITTED
Рассмотрим транзакцию выше. После INSERT данные сразу-же станут доступны для чтения. Тоесть еще до вызова COMMIT вне транзакции можно получить только что добавленные данные. В английской литературе это называется dirty read («грязное чтение»). Этот уровень редко используется на практике, да вообще редко кто меняет эти самые уровни.

Второй READ COMMTITED
В данном случае прочитать данные возможно только после вызова COMMIT. При чем внутри транзакции данные тоже будут еще не доступны. 
Если рассмотреть транзакцию выше, то первый SELECT ничего не вернет, т.к. таблица у нас еще пустая и транзакция не подтверждена. 

Третий REPEATABLE READ
Этот уровень используется по умолчанию в MySQL. Отличается от второго тем, что вновь добавленные данные уже будут доступны внутри транзакции, но не будут доступны до подтверждения извне. 
Здесь может возникнуть теоретическая проблема «фантомного чтения». Когда внутри одной транзакции происходит чтение данных, другая транзакция в этот момент вставляет новые данные, а первая транзакция снова читает те-же самые данные.

И последний SERIALIZABLE
На данном уровне MySQL блокирует каждую строку над которой происходит какое либо действие, это исключает появление проблемы «фантомов». На самом деле смысла использовать этот уровень нет, т.к. InnoDB и менее популярный Falcon решают эту проблему.

Увидеть текущий уровень изоляции

SHOW VARIABLES LIKE '%tx_isolation%';

Установить

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

Это всего лишь попытка вольного перевода самой обычной документации.
Спасибо.

Задачка:

CREATE TABLE one(id INT, value VARCHAR(12)) ENGINE = MyISAM;
CREATE TABLE two(id INT, value VARCHAR(12)) ENGINE = InnoDB;

START TRANSACTION;
INSERT INTO one (id, value) VALUES (1, 'test');
INSERT INTO two (id, value) VALUES (1, 'test');
ROLLBACK;
SELECT * FROM one;
SELECT * FROM two;

Что будет в первой таблице, а что во второй?


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *