Согласно документации MySql, MySql поддерживает блокировку с множественной гранулярностью (MGL).
Открыли терминал-1:
// подключились к mysql
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select id, status from tracking_number limit 5 for update;
+----+--------+
| id | status |
+----+--------+
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 4 | 0 |
| 5 | 0 |
+----+--------+
5 rows in set (0.00 sec)
mysql>
оставили его открытым и открыли терминал-2:
// подключились к mysql
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select id, status from tracking_number limit 5 for update;
<!-- Hangs here. and after some time it says-->
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Хотя есть много строк для извлечения, T2 ждет, пока t1 не завершит работу.
Оставил терминал-1 как есть. Теперь в терминале-2:
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
<!-- case 2.1 -->
mysql> select id, status from tracking_number where id=1;
+----+--------+
| id | status |
+----+--------+
| 1 | 0 |
+----+--------+
1 row in set (0.00 sec)
mysql> select id, status from tracking_number where id=2;
+----+--------+
| id | status |
+----+--------+
| 2 | 0 |
+----+--------+
1 row in set (0.00 sec)
<!-- case 2.2 -->
mysql> select * from tracking_number where id=2 for update;
<!-- Hangs here. and after some time -->
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Но почему в случае 1, T2 ждет тот же набор строк, который T1 заблокировал?
Значит ли это, что запрос select без ограничений (даже с параметром limint. Я пробовал и с другим диапазоном) блокирует всю таблицу?
Открыл терминал и транзакцию:
mysql> update tracking_number set status=4 where status=0 limit 5;
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5 Changed: 5 Warnings: 0
Оставил ее там и открыл другой терминал и транзакцию:
mysql> update tracking_number set status=5 where status=0 limit 5;
T2 не удалась, пока я не зафиксировал (или откатил) T1.