2012-01-13 6 views
25

Согласно документации MySql, MySql поддерживает множественную блокировку детализации (MGL).Поведение MySQL 'select for update'

случай-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 в качестве is.Now в терминале-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. Но почему в случае 1, Т2 ждет того же набора строк, T1 заблокирован?

  2. Означает ли это неограниченный запрос на выбор (даже с параметром limint. Я также пытался использовать другой диапазон) блокирует всю таблицу?

  3. Есть ли способ разрешить транзакции блокировки независимо без указания поля записи (т. Е. Без использования где поле = значение)?
  4. Обычно (или в соответствии с одновременной блокировкой Java) блокировка записи является исключительной и чтение не является. В случае 2.1, хотя записи находятся в режиме блокировки записи, как T2 может читать одни и те же записи? Так как это разрешено, в чем смысл его блокировки?
  5. Корпус 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.

  1. Почему такое поведение?

ответ

22

Позвольте мне пройти через ваши случаях и объяснить, как работают эти замки:

1 случай

T1 хочет обновить несколько строк в тестовой таблице. Эта транзакция помещает фиксацию IX на всю таблицу и блокировку X в первых 5 строках.

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

Итак, мы в порядке.

2,1 случая

T1 хочет обновить несколько строк в тестовой таблице. Эта транзакция помещает блокировку IX на всю таблицу и блокировку X в первых 5 строках.

T2 хочет выбрать несколько строк из тестового стола. И это не накладывает никаких блокировок (поскольку InnoDB обеспечивает неблокирующийся читает)

2,1 случая

T1 хочет обновить несколько строк в тестовой таблице. Эта транзакция помещает блокировку IX на всю таблицу и блокировку X в первых 5 строках.

T2 хочет обновить (выбрать для обновления) несколько строк из тестовой таблицы. Поместите IS на всю таблицу и попытайтесь получить S-блокировку в строке и не получится, потому что X и S являются несовместимыми.


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

Надеется, что это помогает

+0

Благодаря @ravnur. Есть ли способ разрешить транзакциям блокировать самостоятельно без указания поля записи (т. Е. Без использования где field = value)? –

+1

независимо = одновременно? Если «да» нет способа сделать это, за исключением того, что уровень изоляции должен быть «DIRTY READS» (вам лучше не попробовать эту опцию). Если ваш ответ «нет», вы можете попробовать «LOCK TABLE» или установить уровень изоляции как «SERIALIZABLE» (но я полагаю, что ваш ответ должен быть «да»). – ravnur

+0

Мой ответ «да». Спасибо за ваше разъяснение. –

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