Есть транзакция буксировки, транзакция 1 удерживает S-блокировку в строке, транзакция 2 хочет обновить строку, затем транзакция 2 ожидает, затем транзакция 1 также выполняет обновления строки, в это время возникает тупик, яподумать Знаешь, в чем причина?Какова ситуация блокировки здесь?
Я выполнил следующий тест на версии mysql5.6. Есть тупик.
Структура таблицы:
CREATE TABLE `test` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增',
`uni_id` bigint(20) DEFAULT NULL,
`current_status` int(11) DEFAULT '0' ,
`total` int(11) NOT NULL DEFAULT '0' ,
PRIMARY KEY (`id`),
UNIQUE KEY `uni_id_unique` (`uni_id`),
KEY `uni_id_idx` (`uni_id`),
KEY `current_status_idx` (`current_status`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
данные инициализации:
INSERT INTO `test`(`id`, `uni_id`, `current_status`, `total`) VALUES (1, 1, 0, 1);
Следующие операции выполняются в следующем порядке: 1. Первый шаг Транзакция 1:
start transaction;
select * from test where id=1 lock in share mode;
второй шаг
start transaction;
update test set uni_id=1,total=total+1 where uni_id=1;
третий шаг Транзакция 1:
update test set current_status=1 where id=1 and
current_status=0;
, затем произошла разблокировка.
- первый шаг: транзакция 1 удерживает блокировку S.
- секундашаг: транзакция 2 ожидает, и по результатам отладки исходного кода полученная блокировка не удалась.
- третий шаг: тупик
информация о взаимоблокировке:
*** (1) TRANSACTION:
TRANSACTION 4360, ACTIVE 14 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s)
MySQL thread id 2, OS thread handle 0x70000a7f4000, query id 145 localhost 127.0.0.1 root updating
update test set uni_id=1,total=total+1 where uni_id=1
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 4 page no 3 n bits 72 index `PRIMARY` of table `test`.`test` trx id 4360 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 8; hex 8000000000000001; asc ;;
1: len 6; hex 000000001106; asc ;;
2: len 7; hex 83000001360110; asc 6 ;;
3: len 8; hex 8000000000000001; asc ;;
4: len 4; hex 80000000; asc ;;
5: len 4; hex 80000001; asc ;;
*** (2) TRANSACTION:
TRANSACTION 4359, ACTIVE 24 sec starting index read
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1248, 2 row lock(s)
MySQL thread id 1, OS thread handle 0x70000a7b0000, query id 149 localhost 127.0.0.1 root updating
update test set current_status=1 where id=1 and
current_status=0
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 4 page no 3 n bits 72 index `PRIMARY` of table `test`.`test` trx id 4359 lock mode S locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 8; hex 8000000000000001; asc ;;
1: len 6; hex 000000001106; asc ;;
2: len 7; hex 83000001360110; asc 6 ;;
3: len 8; hex 8000000000000001; asc ;;
4: len 4; hex 80000000; asc ;;
5: len 4; hex 80000001; asc ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 4 page no 3 n bits 72 index `PRIMARY` of table `test`.`test` trx id 4359 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
0: len 8; hex 8000000000000001; asc ;;
1: len 6; hex 000000001106; asc ;;
2: len 7; hex 83000001360110; asc 6 ;;
3: len 8; hex 8000000000000001; asc ;;
4: len 4; hex 80000000; asc ;;
5: len 4; hex 80000001; asc ;;
*** WE ROLL BACK TRANSACTION (1)