我正在与mysql5.6.34
合作innoDB
。
发生了死锁,我得到了show engine innodb status
的关注。我不知道死锁是如何发生的,为什么TRANSACTION-2
保持并等待相同的X锁,然后ROLLBACK
呢?
日志:
------------------------ LATEST DETECTED DEADLOCK ------------------------ 2018-08-15 05:58:56 7fdff5872700 *** (1) TRANSACTION: TRANSACTION 81567872, ACTIVE 0 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 4 lock struct(s), heap size 1184, 2 row lock(s), undo log entries 2 MySQL thread id 455326, OS thread handle 0x7fdff9083700, query id 255309181 10.8.201.34 slnbdata update INSERT INTO XXX *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 8065 page no 11084 n bits 192 index `PRIMARY` of table `XXX` trx id 81567872 lock_mode X insert intention waiting Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** (2) TRANSACTION: TRANSACTION 81567879, ACTIVE 0 sec inserting mysql tables in use 1, locked 1 4 lock struct(s), heap size 1184, 2 row lock(s), undo log entries 2 MySQL thread id 455338, OS thread handle 0x7fdff5872700, query id 255309187 10.8.201.34 slnbdata update INSERT INTO XXX *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 8065 page no 11084 n bits 192 index `PRIMARY` of table `XXX` trx id 81567879 lock_mode X Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 8065 page no 11084 n bits 192 index `PRIMARY` of table `XXX` trx id 81567879 lock_mode X insert intention waiting Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** WE ROLL BACK TRANSACTION (2) ------------ TRANSACTIONS ------------
There do have a query before the insert: SELECT pk_1, max(pk_2) FROM table WHERE pk_1 IN (...) GROUP BY pk_1 but no queries between each insert. And let me correct my reply above, the insert statement is: insert into table_name(pk_1,pk_2 ...) values (1,1_1 ...) and insert into table_name(pk_1,pk_2 ...) values (2,2_1 ...) We use foreach of mybatis like this: <insert id="save"> <foreach collection="list" item="item" separator=";"> INSERT INTO ...
CREATE TABLE `customer_address_info` ( `customer_no` char(10) NOT NULL, `addr_index` int(1) unsigned NOT NULL, `addr_type` tinyint(1) NOT NULL, `province_code` char(6) DEFAULT NULL, `province_name` varchar(20) DEFAULT NULL, `city_code` char(6) DEFAULT NULL, `city_name` varchar(50) DEFAULT NULL, `county_code` char(6) DEFAULT NULL, `county_name` varchar(100) DEFAULT NULL, `zip_code` char(6) DEFAULT NULL, `detail` varchar(100) NOT NULL, `status` tinyint(4) unsigned NOT NULL, `create_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `create_user` varchar(30) NOT NULL, `modify_date` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `modify_user` varchar(30) DEFAULT NULL, PRIMARY KEY (`customer_no`,`addr_index`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
答案 0 :(得分:0)
正如我评论的那样,发布的信息不足以查看完整图片并知道真正的原因。我将只分享我的两分钱。
Show ENGINE INNODB STATUS指示每个事务已锁定两行并具有两个未决的提交更改(2行锁定,撤消日志条目2),因此同一事务中应该有其他语句,但不是显示。
事务1正在等待IX锁,这将防止事务2持有X锁;事务2正在等待事务1持有的IX锁。
可以通过从表中选择*来获取IX以进行更新。 OP添加的select语句是一个简单的选择,不需要锁定。
由于您的隔离级别是REPEATABLE_READ(这是MySQL的默认设置),因此在交易期间将保留在交易期间获取的每个锁,因此您需要分析从交易开始到插入语句的查询,以查看可能获得的锁。