记一次死锁事故 Deadlock found when trying to get lock

表结构如下:

 

CREATE TABLE `T_QUESTION_ANSWER` (

  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键 自增',

  `project_id` int(11) DEFAULT NULL COMMENT '项目id',

  `question_id` int(11) DEFAULT NULL COMMENT '题目id',

  `key` varchar(20) DEFAULT NULL COMMENT '题目编号(如 1.1.2)',

  `value` text COMMENT '填空内容(多选之间用逗号隔开)',

  `score` decimal(18,2) DEFAULT NULL COMMENT '得分',

  `update_date` timestamp NULL DEFAULT NULL COMMENT '更新时间',

  `create_date` timestamp NULL DEFAULT NULL COMMENT '创建时间',

  PRIMARY KEY (`id`),

  UNIQUE KEY `INDEX_UNIQUE` (`project_id`,`question_id`)

) ENGINE=InnoDB AUTO_INCREMENT=49741 DEFAULT CHARSET=utf8mb4 COMMENT='题目答案表'

 

在使用压力工具测试时发现:批量插入时报死锁错误。

 

Deadlock found when trying to get lock

 

百度一下,有答案了。

https://www.xuejiayuan.net/blog/24ca9c92d56446e3a525c47f6617cb6d

 

五、解决方案

修改隔离级别为提交读(RC)

修改业务代码逻辑,删除记录之前,先select,确认该记录存在,再执行delete删除该记录。

 

之前:

//删除旧答案

deleteBy(Util.getSimpleMap(new KeyValue<>("projectId", projectId)));

//保存新答案

insertList(questionAnswerList);

 

 

现在:

//删除旧答案

if (questionAnswerMapper.queryCount(Util.getSimpleMap(new KeyValue<>("projectId", projectId))) > 0) {//确保记录存在再删除,不然可能发生死锁

    deleteBy(Util.getSimpleMap(new KeyValue<>("projectId", projectId)));

}

//保存新答案

insertList(questionAnswerList);

你可能感兴趣的:(技术人生,MySQL,死锁)