系统中出现死锁的日志如下:

*** (1) TRANSACTION:
TRANSACTION 1331088253, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 7 lock struct(s), heap size 1184, 3 row lock(s), undo log entries 4
MySQL thread id 14699751, OS thread handle 0x7fc5eaeda700, query id 382901670 172.18.140.10 bms update
INSERT INTO `finance_settlement_detail` (`order_detail_id`, `tenant_id`, `store_id`, `order_id`, `working_type_id`, `working_item_id`, `working_item_base_id`, `working_type_name`, `item_code_all`, `achievements_code`, `price_code`, `item_name_all`, `copies_num`, `one_copies_num`, `show_copies_num`, `unit_num`, `unit_price`, `discount`, `amount`, `standard_unit_price`, `standard_total_price`, `item_code1`, `item_name1`, `item_code2`, `item_name2`, `item_code3`, `item_name3`, `item_code4`, `item_name4`, `item_code5`, `item_name5`, `make_info`, `material_id`, `material_name`, `cost_price`, `cost_amount`, `unit`, `make_order_id`, `complete_num`, `outsourcing`, `create_time`, `customer_hash`, `settlement_hash`, `rate`, `product_name`, `below_lowest_price`, `item_lowest_price`, `type_lowest_discount`, `finance_settlement_id`) VALUES (1236472, 125, 1046, 451483, 655, 54047, NULL, '设计/影像', 'custom', NUL
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1156 page no 24892 n bits 760 index `finance_settlement_id` of table `test`.`finance_settlement_detail` trx id 1331088253 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 1331088264, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
7 lock struct(s), heap size 1184, 3 row lock(s), undo log entries 4
MySQL thread id 14699754, OS thread handle 0x7fc5eacd2700, query id 382901673 172.18.140.10 bms update
INSERT INTO `finance_settlement_detail` (`order_detail_id`, `tenant_id`, `store_id`, `order_id`, `working_type_id`, `working_item_id`, `working_item_base_id`, `working_type_name`, `item_code_all`, `achievements_code`, `price_code`, `item_name_all`, `copies_num`, `one_copies_num`, `show_copies_num`, `unit_num`, `unit_price`, `discount`, `amount`, `standard_unit_price`, `standard_total_price`, `item_code1`, `item_name1`, `item_code2`, `item_name2`, `item_code3`, `item_name3`, `item_code4`, `item_name4`, `item_code5`, `item_name5`, `make_info`, `material_id`, `material_name`, `cost_price`, `cost_amount`, `unit`, `make_order_id`, `complete_num`, `outsourcing`, `create_time`, `customer_hash`, `settlement_hash`, `rate`, `product_name`, `below_lowest_price`, `item_lowest_price`, `type_lowest_discount`, `finance_settlement_id`) VALUES (1247931, 118, 240, 455597, 961, 115484, 40698, '彩色快印', 'csdy a4dm 80
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 1156 page no 24892 n bits 760 index `finance_settlement_id` of table `test`.`finance_settlement_detail` trx id 1331088264 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 1156 page no 24892 n bits 760 index `finance_settlement_id` of table `test`.`finance_settlement_detail` trx id 1331088264 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)
2018-10-26 12:21:54 7fc5eaf5c700InnoDB: transactions deadlock detected, dumping detailed information.
2018-10-26 12:21:54 7fc5eaf5c700

死锁日志分析:

1、事务1执行insert语句等待获得X锁;

2、事务2现持有S锁,但执行insert语句也在等待X锁,这样就存在两个事务间相互等待,死锁产生,Mysql自动回滚了事务2;

3、表引擎为innodb,行锁,在字段finance_settlement_id形成,普通索引而非主键索引;

4、因为Mysql死锁日志打印不完全,无法知道上文死锁产生前的sql语句的执行情况,根据以上还无法完全分析出死锁产生的根本原因。

根据使用Xdebug工具进一步调试跟踪代码执行情况,发现在死锁前有update finance_settlement_detail where finance_settlement_Id = XXX这样的语句,这应该就是死锁产生的”凶手“了。

最终原因分析:

1、innodb引擎下update在默认情况下是行锁,但是在Mysql默认隔离级别(可重复读)下,一旦update更新的数据行不存在,则会产生间隙锁(Gap lock);

2、事务1 update不存在的数据行,产生了Gap lock,事务2 update不存在的数据行,也产生了Gap lock;

3、事务1 insert操作需要等待对方释放X锁,事务2 insert操作也需要等待对方释放X锁,死锁产生,Mysql自动回滚了事务2;

如何解决死锁:

解决死锁的原则就是破坏死锁产生的条件,在以上案例中,只需要判断当对应数据行不存在时,不执行update语句即可。

参考文献:https://www.jianshu.com/p/a96ce670c524

Mysql update后insert造成死锁原因分析及解决的更多相关文章

  1. nginx和Tomcat集成后发生的重定向问题分析和解决

    nginx和Tomcat集成后发生的重定向问题分析和解决 Tomcat前端配置一个HTTP服务器应该是大部分应用的标配了,基本思路就是所有动态请求都反向代理给后端的Tomcat,HTTP服务器来处 理 ...

  2. 一次接口压力测试qps极低原因分析及解决过程

    一次接口压力测试qps极低原因分析及解决过程 9-2日在做内部的性能测试相关培训时,发现注册接口压力测试qps极低(20左右),这个性能指标远不能达到上线标准 ,经过一系列调试,最后定位 98%的时间 ...

  3. 【FAQ】接入HMS Core推送服务,服务端下发消息常见错误码原因分析及解决方法

    HMS Core推送服务支持开发者使用HTTPS协议接入Push服务端,可以从服务器发送下行消息给终端设备.这篇文章汇总了服务端下发消息最常见的6个错误码,并提供了原因分析和解决方法,有遇到类似问题的 ...

  4. JavaScript中的ParseInt("08")和“09”返回0的原因分析及解决办法

    今天在程序中出现一个bugger ,调试了好久,最后才发现,原来是这个问题. 做了一个实验: alert(parseInt("01")),当这个里面的值为01====>07时 ...

  5. Code:Blocks 中文乱码问题原因分析和解决方法

    下面说说修改的地方. 1.修改源文件保存编码在:settings->Editor->gernal settings 看到右边的Encoding group Box了吗?如下图所示: Use ...

  6. MySQL死锁原因分析

    行级锁有三种模式: innodb 行级锁 record-level lock大致有三种:record lock, gap lock and Next-KeyLocks. record lock  锁住 ...

  7. MySQL死锁问题分析及解决方法实例详解(转)

      出处:http://www.jb51.net/article/51508.htm MySQL死锁问题是很多程序员在项目开发中常遇到的问题,现就MySQL死锁及解决方法详解如下: 1.MySQL常用 ...

  8. MySQL This function has none of DETERMINISTIC, NO SQL...错误1418 的原因分析及解决方法

    MySQL开启bin-log后,调用存储过程或者函数以及触发器时,会出现错误号为1418的错误: ERROR 1418 (HY000): This function has none of DETER ...

  9. c# 关于抓取网页源码后中文显示乱码的原因分析和解决方法

    原因分析:首先,目前大多数网站为了提升网页浏览传输速率都会对网站内容在传输前进行压缩,最常用的是GZIP压缩解压解压算法,也是支持最广的一种. 因为网站传输时采用的是GZIP压缩传输,如果我们接受we ...

随机推荐

  1. 深入学习JavaScript: apply 方法 详解

    我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里我做如下笔记,希望和大家 ...

  2. jquery 选择器的总结

    元素选择 $("input") id选择 $('#id') class选择 $('.id') 属性选择 $('[prop]')或者$('[prop=“value1”]')或者$(' ...

  3. MVC项目中的分页实现例子

    在开发项目中,写了一个分页实现的例子,现在把源代码贴上,以供以后写代码时参考 在列表的头部,有如下显示, 这个代表一个页面显示10条记录,总共22条记录. 这个是页面底部的显示 那么如何来显示这个分页 ...

  4. js复习笔记

    isNaN(x) 1.判断结果不是纯数字, var a=1234var b =isNan(a) //b是 false 因为a是纯数字 var a="abc123"var b =is ...

  5. 使用Django创建一个后端是SQLSERVER的简单系统(一)Django连接SQLServer数据库

    window环境下Django连接SQLSERVER, 1.创建项目: 2.创建application: 3.使用pycharm打开项目,如下图: 4.配置虚拟环境: 安装Django\pyodbc\ ...

  6. superset 错误解决

    访问superset localhost:8088   securety->list Role 报错 xxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx ...

  7. GTK+学习笔记(一)

    你将学到什么 如何实现弹出式菜单 菜单简介 菜单(GtkMenu)由菜单项(GtkMenuItem)构成,菜单项可以是任意构件比如按钮.菜单(子菜单) 菜单项的管理 菜单外壳(GtkMenuShell ...

  8. kolla-ansible安装cinder

    LVM后端 环境拓扑 节点 IP 主机名 Controller/Network/Apollo 92.0.0.11 anode Compute/Storage 92.0.0.12 bnode multi ...

  9. C 语言实例 - 实现简单的计算器

    C 语言实例 - 实现简单的计算器 实现加减乘除计算. 实例 # include <stdio.h> int main() { char operator; double firstNum ...

  10. ACM-ICPC 2018 徐州赛区网络预赛-G Trace(线段树的应用

    Problem:Portal传送门 Problem:Portal传送门  原题目描述在最下面.  我理解的题意大概是:有n次涨潮和退潮,每次的范围是个x×y的矩形,求n次涨退潮后,潮水痕迹的长度.   ...