https://blog.csdn.net/a12345555555/article/details/72828366

-08-13 15:12:44 [ERROR] com.zhubajie.coupon.app.CouponReceiveAppServiceImpl {CouponReceiveAppServiceImpl.java:50} - ### Error updating
 database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException:
Deadlock found when trying to get lock; try restarting transaction ### The error may involve defaultParameterMap
 ### The error occurred while setting parameters ### SQL: UPDATE cpn_core_coupon SET coup_num_usr = coup_num_usr + 1 WHERE coup_usr = ? AND spec_id = ? AND coup_num_usr < ?
 ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction ; SQL []; Deadlock found when trying to get lock; try restarting transaction;
nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

错误中提示下面这条sql发生了死锁
UPDATE coupon SET coup_num_usr = coup_num_usr +
1 WHERE coup_usr = ? AND spec_id = ? AND coup_num_usr < ?

首先我们来看下coupon的表结构
CREATE TABLE
`coupon` (
`id`
int(11)
 NOT NULL AUTO_INCREMENT COMMENT ' ',
`spec_id`
char(20)
 NOT NULL COMMENT '优惠券活动编号',
`coup_usr`
char(11)
 DEFAULT NULL COMMENT '优惠券用户',
`coup_num_usr`
int(11)
unsigned NOT NULL DEFAULT
'0' COMMENT
'该用户已领取该活动的券数量', PRIMARY KEY (`id`),
 KEY `coup_usr_idx` (`coup_usr`),
 KEY `spec_idx` (`spec_id`))
 ENGINE=InnoDB AUTO_INCREMENT=8508
 DEFAULT CHARSET=utf8 COMMENT='优惠券';

其中coup usr和spec id是索引,
mysql的事务支持与存储引擎有关,MyISAM不支持事务,INNODB支持事务,更新时采用的是行级锁。这里采用的是INNODB做存储引擎,意味着会将update语句做为一个事务来处理。前面提到行级锁必须建立在索引的基础,这条更新语句用到了索引,所以这里肯定会加上行级锁。
 行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。 这个update语句会执行以下步骤: 1、由于用到了非主键索引,首先需要获取普通索引上的行级锁 2、紧接着根据主键进行更新,所以需要获取主键上的行级锁; 3、更新完毕后,提交,并释放所有锁。
如果在步骤1和2之间突然插入一条语句:UPDATE coupon SET coup num usr
 = coup num usr + 1 WHERE coup usr = ? AND specid
 = ? AND coup num usr < ?
就会发生死锁的情况,因为一条语句获取了普通索引的锁,等待主键锁,另外一条语句获取了主键锁,等待非主键索引,这样就出现了死锁.
如何来解决update ... where ...语句的死锁问题呢?我们可以对其进行分离,首先利用where条件找到主键,然后再利用这些主键去更新数据。
因为select * where ...语句是没有锁的,所以不存在会锁上where条件里面的字段,也就不会发生死锁的情况,只有在update的时候回锁上主键。
所以改成下面两条语句

SELECT id WHERE coup_usr = ? AND spec_id = ?UPDATE coupon SET coup_num_usr = coup_num_usr +
1 WHERE id = ? AND coup_num_usr < ?

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

我在项目中遇到的问题:
1.在更新设备时,使用了批量更新。
解决办法:不要使用批量更新,通过循环的方式一个一个的更新,条件要使用唯一主键uuid
2.更新断网记录时,使用了批量更新,并且条件不是唯一主键
解决办法:不要使用批量更新,查询出断网记录表的每一条数据的主键uuid,使用唯一主键uuid作为更新条件,循环的方式一个一个进行更新。

MySQL更新死锁问题【转,纯为学习】的更多相关文章

  1. MySQL更新死锁问题

    作为一个社交类的 App ,我们有很多操作都会同时发生,为了确保数据的一致性,会采用数据库的事物. 比如现在我们有一个点赞操作,点赞成功后,需要更改文章的热度.以下是 SQL 语句: INSERT I ...

  2. MySql 更新死锁问题 Deadlock found when trying to get lock; try restarting transaction

    文章导航-readme MySql 更新死锁问题 Deadlock found when trying to get lock; try restarting transaction 1.场景 //t ...

  3. MySQL更新数据时,日志(redo log、binlog)执行流程

    1:背景 项目需要做Es和数据库的同步,而手动在代码中进行数据同步又是Es的一些不必要的数据同步操作和业务逻辑耦合,所以使用的了读取mysql的binlog日志的方式进行同步Es的数据. 问题1:根据 ...

  4. MySQL更新锁表超时 Lock wait timeout exceeded

    背景 最近在做一个订单的钉钉审批功能,钉钉审批通过之后,订单更新审核状态,然后添加一条付款,并且更新付款状态: // 订单审批通过 @Transactional(rollbackFor = Excep ...

  5. mysql更新某个字符串字段的部分内容

    如果现在需要Mysql更新字段重部分数据,而不是全部数据,应该采用何种方法呢?下面介绍了两种情况下Mysql更新字段中部分数据的方法,供您参考. Mysql更新字段中部分数据第一种情况: update ...

  6. 警惕 MySql 更新 sql 的 WHERE 从句中的 IN() 子查询时出现的性能陷阱

    警惕 MySql 更新 sql 的 WHERE 从句中的 IN() 子查询时出现的性能陷阱 以下文章来源:https://blog.csdn.net/defonds/article/details/4 ...

  7. MySQL会发生死锁吗?

    SHOW ENGINE INNODB STATUS;来查看死锁日志: SHOW PROCESSLIST;查看进程 MySQL的InnoDB引擎事务有4种隔离级别,主要是为了保证数据的一致性. Inno ...

  8. 热更新(一) 之Lua语法的学习

    热更新 如热更新果需要更换UI显示,或者修改游戏的逻辑,这个时候,如果不使用热更新,就需要重新打包,然后让玩家重新下载(浪费流量和时间,体验不好).热更新可以在不重新下载客户端的情况下,更新游戏的内容 ...

  9. mysql更新日志问题

    [root@localhost ~]# /etc/init.d/mysqld restart 停止 mysqld: [确定] 正在启动 mysqld: [确定] 故障:今天在维护以前数据库日志的时候, ...

随机推荐

  1. axios 发送post请求的时候会发送两次

    第一次发送的时候会先发送OPTIONS, 第二次才发送POST, 解决方法: 引用qs模块 安装qs依赖 npm install qs --save 引入qs依赖 import qs from 'qs ...

  2. 【tomcat环境搭建】Linux和Windows下tomcat开机自启动设置

    目前很多项目都部署在tomcat上,频繁操作中,每次启动或关闭tomcat都稍显麻烦,那如何设置tomcat的开机自启动? Linux下tomcat的开机自启动设置 网上主要有两种方式,一种是shel ...

  3. python基础之作业3----三级菜单小练习

    data = { "华为技术":{ "产品与解决方案":{ "云核心网":{"云核心网研发管理部","云核心网 ...

  4. fastreport窗口重置(适用于属性、数据等窗口显示不出来)

    找到如下路径: C:/Users/账户名/AppData/Local/FastReport/FastReport.config 删除即可. 记得先退出使用FastReport的程序,再删除

  5. 第一章04:JDK与JRE 区别

    JDK = 开发工具 JRE = 运行程序 跨平台性 java程序 = 可以在任何系统中运行(不分系统) JVM = java虚拟机(不同系统下载不一样的JDK版本)(安装的时候包含在jre里面)

  6. equals方法中变量在前和在后的区别

    对于变量:String str1; 使用str1.equals("null"); 对于变量str1,如果str1是null,空是没有equals方法的,会抛出空指针异常 使用&qu ...

  7. css书写规范以及如何写出赏心悦目的代码

    css书写规范: 1. 编码统一为utf-8;2. 协作开发及分工: i根据各个模块, 同时根据页面相似程序, 事先写好大体框架文件,同时根据页面相似程序,事先写好大体框架文件.共用css文件base ...

  8. mui框架上下拉加载

    mui框架被定位为“最接近原生体验的移动App的UI框架”. 写下mui框架中常用的两个功能,下拉刷新和上拉加载,没有后台交互,用js写假数据模拟,下面直接上代码. <!DOCTYPE html ...

  9. Hacklab综合关

    没有注入到底能不能绕过登录 分值: 350 不是SQL注入 通关地址   不是注入,就先扫一下后台,发现在robots.txt后面有 访问一下,发现要先登陆,用burpsuit爆了好久都没有成功,最后 ...

  10. Blinn-Phong模型

    最近在看基础光照模型,比较感兴趣的是高光反射模型,有下列两种: 1.Phong模型 R = 2*N(dot(N, L)) - L specular = lightColor * SpecularCol ...