MySQL更新死锁问题【转,纯为学习】
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更新死锁问题【转,纯为学习】的更多相关文章
- MySQL更新死锁问题
作为一个社交类的 App ,我们有很多操作都会同时发生,为了确保数据的一致性,会采用数据库的事物. 比如现在我们有一个点赞操作,点赞成功后,需要更改文章的热度.以下是 SQL 语句: INSERT I ...
- 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 ...
- MySQL更新数据时,日志(redo log、binlog)执行流程
1:背景 项目需要做Es和数据库的同步,而手动在代码中进行数据同步又是Es的一些不必要的数据同步操作和业务逻辑耦合,所以使用的了读取mysql的binlog日志的方式进行同步Es的数据. 问题1:根据 ...
- MySQL更新锁表超时 Lock wait timeout exceeded
背景 最近在做一个订单的钉钉审批功能,钉钉审批通过之后,订单更新审核状态,然后添加一条付款,并且更新付款状态: // 订单审批通过 @Transactional(rollbackFor = Excep ...
- mysql更新某个字符串字段的部分内容
如果现在需要Mysql更新字段重部分数据,而不是全部数据,应该采用何种方法呢?下面介绍了两种情况下Mysql更新字段中部分数据的方法,供您参考. Mysql更新字段中部分数据第一种情况: update ...
- 警惕 MySql 更新 sql 的 WHERE 从句中的 IN() 子查询时出现的性能陷阱
警惕 MySql 更新 sql 的 WHERE 从句中的 IN() 子查询时出现的性能陷阱 以下文章来源:https://blog.csdn.net/defonds/article/details/4 ...
- MySQL会发生死锁吗?
SHOW ENGINE INNODB STATUS;来查看死锁日志: SHOW PROCESSLIST;查看进程 MySQL的InnoDB引擎事务有4种隔离级别,主要是为了保证数据的一致性. Inno ...
- 热更新(一) 之Lua语法的学习
热更新 如热更新果需要更换UI显示,或者修改游戏的逻辑,这个时候,如果不使用热更新,就需要重新打包,然后让玩家重新下载(浪费流量和时间,体验不好).热更新可以在不重新下载客户端的情况下,更新游戏的内容 ...
- mysql更新日志问题
[root@localhost ~]# /etc/init.d/mysqld restart 停止 mysqld: [确定] 正在启动 mysqld: [确定] 故障:今天在维护以前数据库日志的时候, ...
随机推荐
- UML介绍
UML是什么 Unified Modeling Language (UML)又称统一建模语言或标准建模语言,是始于1997年一个OMG标准,它是一个支持模型化和软件系统开发的图形化语言,为软件开发的所 ...
- Shell脚本 自动部署 SpringBoot 应用
公司项目使用了SpringBoot.开发的应用需要自动上传到服务器.虽然目前对热部署还没完全掌握.先使用shell简化一下部署吧. # 上传密钥 sshLoginKey=/f/MyFile/root. ...
- js截取固定长度字符串,多余字符显示...
function cutstr(str, len) { var str_length = 0; var str_len = 0; str_cut = new String(); str_len = s ...
- Shadow Properties之美(二)【Microsoft Entity Framework Core随笔】
接着上一篇Shadow Properties之美(一),我们来继续举一个有点啰嗦的栗子. 先看简单需求:某HR系统,需要记录员工资料.需要记录的资料有: 员工号(规则:分公司所在城市拼音首字母,加上三 ...
- mybatis源码解析之Configuration加载(三)
概述 上一篇我们主要分析了下<environments>标签下面,transactionManager的配置,上问最后还有个遗留问题:就是在设置事物管理器的时候有个autocommit的变 ...
- this的学习
面试经常被问到this的问题,每次回答都感觉回答的不尽人意,今天周六就在家好好研究this的问题 1.function定义的时候this的指向是无法确定的,执行function的时候才知道this的指 ...
- R语言实战基本方法
R语言的主要功能包括数据统计分析方法和数据可视化,数据分析在这一章中主要学习创建基本图形和基本数据分析 一 基本图形 1条形图 barplot(height) //添加一个条形图,height是一个 ...
- net core 随笔
UseApplicationInsights 这个有用到azure 才有用, 平时没用的话可以去掉. 遥测. 上下文指的是 进程间占有的资源空间. 当一个进程时间片到了或者资缺的时候就会让出CPU ...
- (一)java异常处理的几个问题
1.java中两种异常? 答:java中存在两种异常:受检查(checked)异常和不受检查(unchecked)异常.不受检查的异常不需要在方法或者构造函数上声明,就算是方法或是构造函数会发生这样的 ...
- LeetCode 56 合并区间
题目: 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 [ ...