Согласно документации MySql, MySql поддерживает множественную блокировку гранулярности (MGL).
случай-1
Открыт терминал-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 не завершится.
случай-2
Левый терминал-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?
Означает ли это, что неограниченный запрос на выборку (даже с параметром limint. Я пробовал также с другим диапазоном) блокирует всю таблицу?
- Есть ли способ разрешить независимой блокировке транзакций без указания поля записи (т. Е. Без использования , где field = value )?
- Обычно (или в соответствии с одновременной блокировкой Java) блокировка записи является исключительной, а чтение - нет. В случае 2.1, хотя записи находятся в режиме блокировки записи, как T2 может читать те же записи? Так как это разрешено, какой смысл его блокировать?
- Случай 2.2 понятен.
Открыт терминал и транзакция:
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.
- Почему это поведение?