MySql Deadlock на уже приобретенных замках - PullRequest
3 голосов
/ 19 сентября 2011

Я попал в тупик, который озадачивает меня.Я прочитал в другом посте Требуется объяснение тупика Mysql ответ, который не решил мою путаницу.Ситуация также обнаружена на другой ссылочной странице объяснения о SHOW INNODB STATUS .

Я также присоединяю свой экземпляр - который немного отличается, так как он однажды блокирует индексс пробелами и один раз без.

Но я думаю, что главный вопрос все тот же:

Если транзакция (2) имеет блокировку A , то транзакция (1) ожидает блокировки A , может ли быть так, что транзакция (2) будет заблокирована, если она снова запросит блокировку A ?

Это нене правильно, хотя это то, что мы видим в статусе InnoDb.Когда я пытаюсь воссоздать непосредственно в MySql, используя разные вкладки для разных транзакций - все работает отлично, и такой тупик не существует.Я также прилагаю свою тщетную попытку воссоздать.

Я, вероятно, что-то упускаю в своей интерпретации ситуации, и я был бы очень признателен за хорошее объяснение.

Я использую MySql 5.1,с Hibernate 3.

------------------------
LATEST DETECTED DEADLOCK
------------------------
110918 14:56:36
*** (1) TRANSACTION:
TRANSACTION 0 40261686, ACTIVE 0 sec, process no 1686, OS thread id 1358170432 updating or deleting
mysql tables in use 1, locked 1
LOCK WAIT 9 lock struct(s), heap size 3024, undo log entries 1
MySQL thread id 101203, query id 77147262 localhost 127.0.0.1 operator Updating
update test_table set created='2011-09-18 14:56:28', customer_id=3, ended=null, lead_id=423, message=null, modified='2011-09-18 14:56:36', priority=0, project_id=74, retries=0, started='2011-09-18 14:56:36', status='PROCESS', user_id=2, inquiry_id=1542 where id=1541
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 7148 n bits 952 index `status` of table `test_table` trx id 0 40261686 lock_mode X locks gap before rec insert intention waiting
*** (2) TRANSACTION:
TRANSACTION 0 40261595, ACTIVE 0 sec, process no 1686, OS thread id 1360034112 updating or deleting, thread declared inside InnoDB 499
mysql tables in use 1, locked 1
9 lock struct(s), heap size 3024, undo log entries 2
MySQL thread id 101209, query id 77147276 localhost 127.0.0.1 operator Updating
update test_table set created='2011-09-18 14:53:22', customer_id=3, ended=null, lead_id=401, message='', modified='2011-09-18 14:56:36', priority=0, project_id=74, retries=3, started='2011-09-18 14:55:46', status='PENDING', user_id=2, inquiry_id=1474 where id=1473
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 7148 n bits 952 index `status` of table `test_table` trx id 0 40261595 lock_mode X
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 7148 n bits 952 index `status` of table `test_table` trx id 0 40261595 lock_mode X locks gap before rec insert intention waiting
*** WE ROLL BACK TRANSACTION (1)

попытка воссоздания (я отбросил несколько столбцов с внешними ключами - как они не упоминались в статусе InnoDb):

1) начальная настройка:

DROP TABLE IF EXISTS `knowledge`.`aaa`;
CREATE TABLE  `knowledge`.`aaa` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `message` longtext,
  `status` varchar(16) DEFAULT NULL,
  `priority` int(11) NOT NULL DEFAULT '0',
  `retries` int(8) NOT NULL DEFAULT '0',
  `modified` datetime DEFAULT NULL,
  `customer_id` int(11) unsigned NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`),
  KEY `status` (`status`),
  KEY `customer_id` (`customer_id`) -- ,
  -- CONSTRAINT `aaa_customer_fk` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=515 DEFAULT CHARSET=utf8;


insert into aaa
values (1, '', 'AAA', 0, 0, null, 1);
insert into aaa
values (2, '', 'AAA', 0, 0, null, 1);
insert into aaa
values (3, '', 'AAA', 0, 0, null, 1);

2) Транзакция 2: начать транзакцию (я использую графический интерфейс), предположительно получая первую блокировку транзакции 2

select * from aaa where status = 'AAA' for update;

3) Транзакция 1: начать транзакцию, предположительно ожидая блокировки- Кстати, транзакция действительно ждет.

insert into aaa
values (10, '', 'BBB', 0, 0, null, 1);

4) Транзакция 2: предположительно, снова пытается ожидать такой же блокировки - Кстати, это вообще не ждет.

update aaa set status = 'BBB' where id = 1;
update aaa set status = 'BBB' where id = 2;

теперь я могу совершить транзакцию 2, а затем транзакцию 1 и все в порядке ... нет воссоздания тупиковой ситуации ..

...