MySQL
MySQL LOCK TABLE
Поиск…
Синтаксис
LOCK TABLES table_name [READ | ЗАПИСЫВАТЬ]; // Стол блокировки
РАЗБЛОКИРОВАТЬ ТАБЛИЦЫ; // Разблокировать таблицы
замечания
Блокировка используется для решения проблем параллелизма. Блокировка требуется только при выполнении транзакции, которая сначала считывает значение из базы данных и позже записывает это значение в базу данных. Замки никогда не требуются для самостоятельной операции вставки, обновления или удаления.
Доступны два вида замков
READ LOCK - когда пользователь только читает из таблицы.
WRITE LOCK - когда пользователь выполняет чтение и запись в таблицу.
Когда пользователь удерживает WRITE LOCK
на таблице, другие пользователи не могут читать или писать в эту таблицу. Когда пользователь держит READ LOCK
на таблице, другие пользователи также могут читать или удерживать READ LOCK
, но никто не может писать или удерживать WRITE LOCK
в этой таблице.
Если основным механизмом хранения данных является InnoDB, MySQL автоматически использует блокировку на уровне строк, так что несколько транзакций могут использовать одну и ту же таблицу одновременно для чтения и записи, не заставляя друг друга ждать.
Для всех систем хранения, отличных от InnoDB, MySQL использует блокировку таблиц.
Более подробная информация о блокировке таблиц См. Здесь
Замки Mysql
Столбцы могут быть важным инструментом для ENGINE=MyISAM
, но редко используются для ENGINE=InnoDB
. Если у вас возникли соблазны использовать блокировки таблиц с InnoDB, вы должны пересмотреть, как вы работаете с транзакциями.
MySQL позволяет клиентским сеансам явно получать блокировки таблиц с целью взаимодействия с другими сеансами для доступа к таблицам или для предотвращения изменения других сеансов в периоды, когда сеанс требует эксклюзивного доступа к ним. Сеанс может приобретать или выпускать блокировки только для себя. Один сеанс не может получить блокировки для другого сеанса или блокировки релиза, проводимые другим сеансом.
Замки могут использоваться для эмуляции транзакций или для увеличения скорости при обновлении таблиц. Это объясняется более подробно ниже в этом разделе.
Команда: LOCK TABLES table_name READ|WRITE;
вы можете назначить только тип блокировки для одной таблицы;
Пример (READ LOCK):
LOCK TABLES table_name READ;
Пример (WRITE LOCK):
LOCK TABLES table_name WRITE;
Чтобы увидеть блокировку, применяется или нет, используйте следующую команду
SHOW OPEN TABLES;
Чтобы очистить / удалить все блокировки, используйте следующую команду:
UNLOCK TABLES;
ПРИМЕР:
LOCK TABLES products WRITE:
INSERT INTO products(id,product_name) SELECT id,old_product_name FROM old_products;
UNLOCK TABLES;
Выше примера, любое внешнее соединение не может записывать какие-либо данные в таблицу продуктов, пока не будет разблокирован настольный продукт
ПРИМЕР:
LOCK TABLES products READ:
INSERT INTO products(id,product_name) SELECT id,old_product_name FROM old_products;
UNLOCK TABLES;
Вышеприведенный пример, любое внешнее соединение не может читать данные из таблицы продуктов, пока не будет разблокирован настольный продукт
Блокировка уровня строки
Если в таблицах используется InnoDB, MySQL автоматически использует блокировку на уровне строк, чтобы несколько транзакций могли одновременно использовать одну и ту же таблицу для чтения и записи, не заставляя друг друга ждать.
Если две транзакции, пытающиеся изменить одну и ту же строку, и оба используют блокировку уровня строки, одна из транзакций ждет другого.
Блокировка уровня строк также может быть получена с помощью SELECT ... FOR UPDATE
для каждой строки, которая, как ожидается, будет изменена.
Рассмотрим два подключения для подробного объяснения блокировки уровня строк
Соединение 1
START TRANSACTION;
SELECT ledgerAmount FROM accDetails WHERE id = 1 FOR UPDATE;
В соединении 1 блокировка уровня строки, полученная SELECT ... FOR UPDATE
.
Соединение 2
UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1;
Когда кто-то пытается обновить ту же строку в соединении 2, которая будет ждать соединения 1 для завершения транзакции или сообщения об ошибке, будет отображаться в соответствии с параметром innodb_lock_wait_timeout
, который по умолчанию составляет 50 секунд.
Error Code: 1205. Lock wait timeout exceeded; try restarting transaction
Чтобы просмотреть сведения об этой блокировке, запустите SHOW ENGINE INNODB STATUS
---TRANSACTION 1973004, ACTIVE 7 sec updating
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 4, OS thread handle 0x7f996beac700, query id 30 localhost root update
UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1
------- TRX HAS BEEN WAITING 7 SEC FOR THIS LOCK TO BE GRANTED:
Соединение 2
UPDATE accDetails SET ledgerAmount = ledgerAmount + 250 WHERE id=2;
1 row(s) affected
Но при обновлении некоторой другой строки в соединении 2 будет выполняться без какой-либо ошибки.
Соединение 1
UPDATE accDetails SET ledgerAmount = ledgerAmount + 750 WHERE id=1;
COMMIT;
1 row(s) affected
Теперь блокировка строки освобождается, поскольку транзакция завершается в Connection 1.
Соединение 2
UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1;
1 row(s) affected
Обновление выполняется без каких-либо ошибок в Connection 2 после того, как Connection 1 освободил блокировку строки, завершив транзакцию.