Почему эта простая транзакция sql хочет больше S-блокировки после удержания X-блокировки? - PullRequest
0 голосов
/ 29 мая 2020

определение моей таблицы выглядит так:

 CREATE TABLE `test_table` (
  `a` int,
  `b` int,
  PRIMARY KEY (`a`),
  UNIQUE KEY `idx_b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

, а уровень изоляции: Read Committed (R C)

, а запрос sql похож на: update test_table set a=LAST_INSERT_ID(a + 1) WHERE b= 1;

когда несколько клиентов запрашивают выполнение одного и того же SQL в одно и то же время, mysql может возникнуть ошибка взаимоблокировки, а журнал взаимоблокировок имеет вид:

------------------------
LATEST DETECTED DEADLOCK
------------------------
2020-05-26 18:04:12 0x7efb06c5d700
*** (1) TRANSACTION:
TRANSACTION 261901143, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 6018875, OS thread handle 139617907197696, query id 3320727857 10.202.6.165 ma88 updating
update test_table set a=LAST_INSERT_ID(a + 1) WHERE b=1
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 6485 page no 4 n bits 272 index idx_b of table test_db.test_table trx id 261901143 lock_mode X locks rec but not gap waiting
Record lock, heap no 148 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
 0: len 1; hex 06; asc  ;;
 1: len 4; hex 00aeae62; asc    b;;

*** (2) TRANSACTION:
TRANSACTION 261901142, ACTIVE 0 sec updating or deleting, thread declared inside InnoDB 4999
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 2
MySQL thread id 6018874, OS thread handle 139616615520000, query id 3320727856 10.202.6.165 ma88 updating
update test_table set a=LAST_INSERT_ID(a + 1) WHERE b=1
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 6485 page no 4 n bits 272 index idx_b of table test_db.test_table trx id 261901142 lock_mode X locks rec but not gap
Record lock, heap no 148 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
 0: len 1; hex 06; asc  ;;
 1: len 4; hex 00aeae62; asc    b;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 6485 page no 4 n bits 272 index idx_b of table test_db.test_table trx id 261901142 lock mode S waiting
Record lock, heap no 148 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
 0: len 1; hex 06; asc  ;;
 1: len 4; hex 00aeae62; asc    b;;

*** WE ROLL BACK TRANSACTION (1)

через этот журнал взаимоблокировок, я обнаружил, что: транзакция-1 ожидает блокировки X, которая удерживается транзакцией-2, а транзакция-2 хочет S-блокировку для тех же данных, а затем тупик.

чего я не мог понять вот почему транзакция-2 хочет S Lock, в то время как в этом случае она удерживает X Lock.

может ли кто-нибудь дать мне ответ или какую-нибудь идею?

1 Ответ

0 голосов
/ 04 июня 2020

Рассмотрите возможность выведения UPDATE из транзакции. Это может привести к «сжиганию» некоторых порядковых номеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...