MySql Deadlock на уже приобретенных замках

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

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

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

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

Это не звучит правильно, хотя это то, что мы видим в статусе 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, и все в порядке... нет воссоздания тупиковой ситуации..

0 ответов

Другие вопросы по тегам