http://blog.csdn.net/aesop_wubo/article/details/8286215


问题描述

在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下:

表结构如下:

SQL语句如下:

update user_item setstatus=1 where user_id=? and item_id=?

原因分析

MySQL的事务支持与存储引擎有关,MyISAM不支持事务,INNODB支持事务,更新时采用的是行级锁。这里采用的是INNODB做存储引擎,意味着会将update语句做为一个事务来处理。前面提到行级锁必须建立在索引的基础,这条更新语句用到了索引idx_1,所以这里肯定会加上行级锁。

行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。

这个update语句会执行以下步骤:

1、由于用到了非主键索引,首先需要获取idx_1上的行级锁

2、紧接着根据主键进行更新,所以需要获取主键上的行级锁;

3、更新完毕后,提交,并释放所有锁。

如果在步骤1和2之间突然插入一条语句:update user_item set status=? where id=? and user_id=? ,这条语句会先锁住主键索引,然后锁住idx_1。

蛋疼的情况出现了,一条语句获取了idx_1上的锁,等待主键索引上的锁;另一条语句获取了主键上的锁,等待idx_1上的锁,这样就出现了死锁。

解决方案

1、先获取需要更新的记录的主键

select id from user_item where user_id=? and item_id=?

2、逐条更新

update user_item set status=? where id=? anduser_id=?

这样貌似解决了,都是对单条进行操作,都是先获取主键上的锁,再获取idx_1上的锁。

不过这个解决方案与先前的更新语句不一样,

先前的更新语句对所有记录的更新在一个事务中,采用循环更新后并不在同一个事务中,所以在for循环外面还得开一个事务。

小结

在采用INNODB的MySQL中,更新操作默认会加行级锁,行级锁是基于索引的,在分析死锁之前需要查询一下mysql的执行计划,看看是否用到了索引,用到了哪个索引,对于没有用索引的操作会采用表级锁。如果操作用到了主键索引会先在主键索引上加锁,然后在其他索引上加锁,否则加锁顺序相反。在并发度高的应用中,批量更新一定要带上记录的主键,优先获取主键上的锁,这样可以减少死锁的发生。

MySql批量更新死锁案例分析相关推荐

  1. MySQL批量更新死锁案例分析--转载

    问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下: [java] view plaincopyprint? com.mysql.jdbc.exceptions.jdb ...

  2. mysql批量插入死锁问题分析(正序VS逆序)

    2019独角兽企业重金招聘Python工程师标准>>> https://dev.mysql.com/doc/refman/5.5/en/innodb-locking.html#inn ...

  3. mysql 批量更新

    mysql更新语句很简单,更新一条数据的某个字段,一般这样写: 复制代码代码如下: UPDATE mytable SET myfield = 'value' WHERE other_field = ' ...

  4. mysql批量更新,批量插入之replace语句/insert into... on duplicate key update语句

    mysql批量更新/插入数据有以下方法,使用这些方法批量插入数据/更新数据的时候就不用在代码层次增加判断数据是否已存在的逻辑了. 1:replace语句 2: insert into... on du ...

  5. mysql 批量更新数据 备份_mysql 批量更新与批量更新多条记录的不同值实现方法...

    批量更新 mysql更新语句很简单,更新一条数据的某个字段,一般这样写: UPDATE mytable SET myfield = 'value' WHERE other_field = 'other ...

  6. dapper mysql 批量_MySQL数据库之c#mysql批量更新的两种方法

    本文主要向大家介绍了MySQL数据库之c#mysql批量更新的两种方法 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 总体而言update 更新上传速度还是慢. 1:  简单的 ...

  7. mybatis之(Oracle,MySql)批量更新

    Oracle和MySql批量更新配置文件不太一样. Oracle: <!-- 对应关系批量更新 --><update id="hotelCusRelUpdate" ...

  8. mysql循环更新数据_大批量更新数据mysql批量更新的四种方法

    mysql 批量更新如果一条条去更新效率是相当的慢, 循环一条一条的更新记录,一条记录update一次,这样性能很差,也很容易造成阻塞. mysql 批量更新共有以下四种办法 1..replace i ...

  9. 大批量更新数据mysql批量更新的四种方法

    转载一篇大批量更新mysql数据的办法,为了便于阅读根据原文做了缩减. mysql 批量更新如果一条条去更新效率是相当的慢, 循环一条一条的更新记录,一条记录update一次,这样性能很差,也很容易造 ...

最新文章

  1. 5. 编程规范和编程安全指南--JavaScript
  2. TensorFlow2.0正式版发布,极简安装TF2.0(CPUGPU)教程
  3. 服务器常用shell巡检脚本
  4. strtotime()加半个小时_椰子鸡这样做太好吃了,一滴水不用加,鲜香嫩滑,做法非常简单...
  5. SpringMVC 通过post接收form参数或者json参数
  6. erp采购总监个人总结_2018计划工作年终总结和2019目标:助理版、经理版、总监版(二)...
  7. centos常用网络管理命令
  8. 可有可无的Mysql工作技巧 2
  9. ekho tts 下载_Ekho TTS简介(文本转语音引擎).pptx
  10. linux系统英伟达gpu驱动卸载_英伟达显卡驱动程序被发现强制捆绑 官方已火速撤回驱动下载链接...
  11. JavaScript基本数据类型和引用数据类型
  12. 关于==和equals的探索
  13. c语言成绩查询系统_如何用Excel制作成绩查询系统-Leo老师
  14. Java算法-冒泡排序
  15. 矩阵分析与应用(一)
  16. undo歌词中文音译_undo的中文谐音歌词
  17. CEIWEI CommMonitor 串口监控精灵v11.0 串口过滤 串口驱动
  18. 测试工程师-压力测试之jmeter脚本
  19. java数据结构和算法——前缀表达式(即波兰表达式)、中缀表达式及后缀表达式(即逆波兰表达式)介绍
  20. python平安夜代码加文案

热门文章

  1. vue 左右滑动菜单_Vue实现左右菜单联动实现代码
  2. Linux PXE批量网络装机与Kickstart 无人值守安装
  3. abap 函数远程启用的模块参数_SAP AMDP介绍 - ABAP托管的HANA数据库过程
  4. python做数据库管理系统_python+Django+mysql+bootstrap前端,数据库一次搞定)从头教你毕设实现一个简易好看的仓储物资管理之类系统...
  5. 中标麒麟linux系统忘记root密码,中标麒麟(龙芯CPU)--忘记root密码怎么修改?
  6. 俄亥俄州立大学计算机专业排名,美国俄亥俄州立大学各专业的排名情况介绍
  7. k8s pod之间不能通信_Kubernetes 同 Pod 内的容器使用共享卷通信
  8. python小案例_Python的应用小案例
  9. 服务器每秒钟执行命令数量是什么_全国自考互联网及其应用模拟试卷(一)及答案.doc...
  10. 计算机的硬件简介,计算机基础之硬件简介(Day2)(示例代码)