Spec-Zone .ru
спецификации, руководства, описания, API
|
Непротиворечивое чтение
означает это InnoDB
мультиуправление версиями использования, чтобы представить
запросу снимок базы данных в моменте времени. Запрос видит изменения, произведенные транзакциями, которые
фиксировали перед тем моментом времени, и никакими изменениями, произведенными позже, или отменили фиксацию
транзакции. Исключение к этому правилу - то, что запрос видит изменения, произведенные более ранними операторами
в пределах той же самой транзакции. Это исключение вызывает следующую аномалию: Если Вы обновляете некоторые
строки в таблице, a SELECT
видит последнюю версию обновленных строк, но она могла бы также видеть
более старые версии любых строк. Если другие сеансы одновременно обновляют ту же самую таблицу, аномалия
означает, что Вы могли бы видеть таблицу в состоянии, которое никогда не существовало в базе данных.
Если уровень изоляции
транзакции REPEATABLE
READ
(уровень значения по умолчанию), все непротиворечивые чтения в пределах того же самого чтения
транзакции снимок, установленный первым такое чтение в той транзакции. Можно получить более новый снимок для
своих запросов, фиксируя текущую транзакцию и после тот выходящие новые запросы.
С READ COMMITTED
уровень изоляции, каждое непротиворечивое чтение в пределах транзакции устанавливает и читает свой собственный
новый снимок.
Непротиворечивое чтение является режимом по умолчанию в который InnoDB
процессы SELECT
операторы в READ
COMMITTED
и REPEATABLE READ
уровни изоляции. Непротиворечивое чтение не устанавливает,
любой соединяет таблицы, к которым оно получает доступ, и поэтому другие сеансы свободны изменить те таблицы
одновременно, непротиворечивое чтение выполняется на таблице.
Предположите, что Вы работаете в значении по умолчанию REPEATABLE READ
уровень изоляции. Когда Вы выпускаете непротиворечивое чтение (то
есть, дежурное блюдо SELECT
оператор), InnoDB
дает Вашей транзакции
timepoint, согласно которому Ваш запрос видит базу данных. Если другая транзакция удаляет строку и фиксации
после того, как Ваш timepoint был присвоен, Вы не видите строку, как удаленную. Вставляет и обновления
обрабатываются так же.
Снимок состояния базы данных применяется к SELECT
операторы в пределах транзакции, не обязательно к операторам DML. Если Вы вставляете или
изменяете некоторые строки и затем фиксируете ту транзакцию, a DELETE
или UPDATE
заявление, сделанное от другого параллельного REPEATABLE READ
транзакция могла влиять на те только фиксировавшие строки,
даже при том, что сеанс не мог запросить их. Если транзакция действительно обновляет или удаляет строки,
фиксировавшие различной транзакцией, те изменения действительно становятся видимыми к текущей транзакции.
Например, Вы могли бы встретиться с ситуацией как следующее:
SELECT COUNT(c1) FROM t1 WHERE c1 = 'xyz'; -- Returns 0: no rows match.DELETE FROM t1 WHERE c1 = 'xyz'; -- Deletes several rows recently committed by other transaction.SELECT COUNT(c2) FROM t1 WHERE c2 = 'abc'; -- Returns 0: no rows match.UPDATE t1 SET c2 = 'cba' WHERE c2 = 'abc'; -- Affects 10 rows: another txn just committed 10 rows with 'abc' values.SELECT COUNT(c2) FROM t1 WHERE c2 = 'cba'; -- Returns 10: this txn can now see the rows it just updated.
Можно усовершенствовать свой timepoint, фиксируя Вашу транзакцию и затем делая другого SELECT
или START TRANSACTION WITH CONSISTENT SNAPSHOT
.
Это вызывают мультиимеющим версию управлением совместным выполнением.
В следующем примере сеанс A видит строку, вставленную B только, когда B фиксировал вставку, и A фиксировал также, так, чтобы timepoint был усовершенствован мимо фиксации B.
Session A Session B SET autocommit=0; SET autocommit=0;time| SELECT * FROM t;| empty set| INSERT INTO t VALUES (1, 2);|v SELECT * FROM t; empty set COMMIT; SELECT * FROM t; empty set COMMIT; SELECT * FROM t; --------------------- | 1 | 2 | --------------------- 1 row in set
Если Вы хотите видеть "самое новое" состояние
базы данных, используйте любого READ COMMITTED
уровень изоляции или блокировка
читают:
SELECT * FROM t LOCK IN SHARE MODE;
С READ COMMITTED
уровень изоляции, каждое непротиворечивое чтение в пределах транзакции устанавливает и читает свой собственный
новый снимок. С LOCK IN SHARE MODE
, чтение блокировки происходит вместо этого: A
SELECT
блоки до транзакции, содержащей самые новые концы строк (см. Раздел
14.2.3.4, "Блокируя Чтения (SELECT ... FOR UPDATE
и SELECT
... LOCK IN SHARE MODE
)").
Непротиворечивое чтение не работает по определенным операторам DDL:
Непротиворечивое чтение не работает DROP TABLE
, потому что MySQL не может использовать таблицу, которая была
отброшена и InnoDB
уничтожает таблицу.
Непротиворечивое чтение не работает ALTER TABLE
, потому что тот оператор делает временную копию исходной
таблицы и удаляет исходную таблицу, когда временная копия создается. Когда Вы переиздаете
непротиворечивое чтение в пределах транзакции, строки в новой таблице не видимы, потому что те строки не
существовали, когда снимок транзакции был взят. В этом случае транзакция возвращает ошибку с MySQL
5.6.6: ER_TABLE_DEF_CHANGED
,
"Табличное определение изменилось, пожалуйста, повторите транзакцию".
Тип чтения изменяется для, выбирает в пунктах как INSERT
INTO ... SELECT
, UPDATE ... (SELECT)
, и CREATE TABLE ... SELECT
это не определяет FOR UPDATE
или LOCK IN SHARE MODE
:
По умолчанию, InnoDB
использует более сильные
блокировки и SELECT
часть действует как READ COMMITTED
, где каждое непротиворечивое чтение, даже в пределах
той же самой транзакции, устанавливает и читает свой собственный новый снимок.
Чтобы использовать непротиворечивое чтение в таких случаях, включите innodb_locks_unsafe_for_binlog
опция и набор уровень изоляции транзакции
к READ
UNCOMMITTED
, READ COMMITTED
, или REPEATABLE READ
(то есть, что-либо кроме SERIALIZABLE
). В этом случае никакие блокировки не устанавливаются на
строках, считанных из выбранной таблицы.