2012-01-25 4 views
1

Я разработчик и имею только хорошие знания о базах данных. Мне нужно понять механизм блокировки уровня транзакций в InnoDB.Mysql InnoDB - сценарий блокировки

Я читал, что InnoDB использует блокировку на уровне строк? Насколько я понимаю, он блокирует определенную строку внутри транзакции. Что произойдет с оператором select при обновлении таблицы?

Например, предположим, что транзакция и оператор выбора инициируются двумя разными процессами и предполагают, что Transaction1 запускается до выдачи оператора select.

Transaction1 : Start 
Update table_x set x = y where 1=1 
Transaction1 : End 

Select Query

Select x from table_x 

Что будет с отборного заявления. Будет ли он возвращать значения «во время» Transaction1 имеет место или «после» завершается? И если он может начаться только после завершения транзакции1, где находится блокировка уровня строки на этом снимке?

Я понимаю смысл или мое фундаментальное понимание само по себе неправильно? Пожалуйста, порекомендуйте.

+1

Я не думаю, что выбрать будет вызывать ничего, он возвращает результат также InnoDB обрабатывает транзакции динамически вы не должны указать явную транзакцию с использованием START TRANSACTION и конца с помощью COMMIT для одного запроса. Однако START TRANSACTION применит LOCK, который может быть выпущен только после COMMIT –

+0

@MaheshPatil: очень хороший момент, я обновил вопрос. – bragboy

ответ

2

Это зависит не только от блокировки участвующих, но на уровне изоляции, которая использует блокировки, чтобы обеспечить изоляцию транзакций, как это определено Стандарты ACID. InnoDB использует не только блокировку, но и многоверсию строк для ускорения транзакций.

В уровне изоляции serializable он будет использовать блокировку чтения с обновлением, поэтому для выбора нужно будет дождаться завершения первой транзакции.Однако при более низких уровнях изоляции блокировка будет записываться, а выбор не будет заблокирован. В repeatable read и read committed он сканирует журнал отката, чтобы получить предыдущее значение записи, если оно обновлено, а в read uncommitted в будет возвращать текущее значение.

Разница между блокировкой на уровне таблицы и блокировкой на уровне строк - это когда у вас есть 2 транзакции, которые запускают запрос на обновление. При блокировке на уровне таблицы второй должен будет ждать первый, так как вся таблица заблокирована. При блокировке на уровне строк будут заблокированы только строки, соответствующие условию where * (а также некоторые промежутки между ними, но это еще одна тема), что означает, что разные транзакции могут обновлять разные части таблицы, не нужно ждать друг для друга.

* при условии, что есть индекс покрытия, где положение

1

SELECT, запущенный за пределами транзакции, увидит таблицу, как это было до начала транзакции. Он увидит обновленные значения только после того, как будет проведена транзакция.

2

Выбор не будет ждать завершения транзакции, вместо этого он вернет текущее значение строк (иначе, до начала транзакции).

Если вы хотите выбрать, чтобы ждать сделки до конца вы можете использовать «LOCK IN SHARE MODE»:

Select x from table_x LOCK IN SHARE MODE; 

Это заставит выбрать ждать любого ряда (ов), которые в настоящее время блокировки посредством транзакции с исключительной (обновлением/удалением) блокировкой на них.

Считывание производится с LOCK IN SHARE MODE читает последние доступные данные и устанавливает общий режим блокировки на чтение строки. Блокировка общего режима не позволяет другим пользователям обновлять или удалять прочитанные строки. Кроме того, если последние данные принадлежат к еще не завершенной транзакции еще одного сеанса , мы дождаемся окончания этой транзакции.

http://dev.mysql.com/doc/refman/5.0/en/innodb-lock-modes.html

3

Это зависит от уровня изоляции.

SERIALIZABLE 
REPEATABLE READS 
READ COMMITTED 
READ UNCOMMITTED 

Хорошо объяснено на wikipedia

И в MYSQL docu

Смежные вопросы