文档章节

MySQL 出现死锁的分析和解决方案

黄途文
 黄途文
发布于 2015/07/16 12:47
字数 526
阅读 16291
收藏 9

异常日志

### 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 t_withdraw_apply SET last_apply_time=? WHERE user_id = ? AND state = 0

### 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 t_withdraw_apply SET last_apply_time=? WHERE user_id = ? AND state = 0

再看业务逻辑

int i = withdrawApplyDAO.add(apply);

    if(i == 1) {

      //获取该用户最早的待提现申请时间

      Timestamp earlierTime = withdrawApplyDAO.getEarlierApplyTime(userId);

      withdrawApplyDAO.updateEarlierApplyTime(userId,earlierTime);//更新冗余字段

      //扣除账户余额,然后写入gold_log日志

      int j = userDAO.updateUserGold(0-amount, userId);

......

那么为什么会出现死锁呢?


原来是这样的,用户点击过快同时提交了两次提现申请

那么就会开启两个事务

事务1 插入一条apply

事务2 也插入一条apply

事务1 执行更新 updateEarlierApplyTime ,由于事务2插入的数据也需要更新,所以这个时候 事务1需要等待事务2提交后才能执行

事务2 页执行更新 updateEarlierApplyTime ,同样需要更新事务1插入的输入,也需要等地事务1完成才能继续执行,这样就出现了死锁


怎么解决这个问题呢?

首先出现这个问题的原因是事务1更新的数据包含了事务2插入的数据,事务2更新也包含了事务1插入的数据,那么我们可以让代码改为

 withdrawApplyDAO.updateEarlierApplyTime(userId,earlierTime);//更新冗余字段

 withdrawApplyDAO.add(apply);

这样就能解决死锁问题

其次,出现这样的问题是用户重复提交导致的,所以应该做重复提交的限制,


© 著作权归作者所有

共有 人打赏支持
黄途文
粉丝 3
博文 7
码字总数 4595
作品 0
成都
程序员
私信 提问
加载中

评论(3)

泥沙砖瓦浆木匠
泥沙砖瓦浆木匠

引用来自“黄途文”的评论

引用来自“泥沙砖瓦浆木匠”的评论

看看我关于秒杀处理。博客

给个链接看看,我没有看见你的秒杀文章

就 锁机制13
黄途文
黄途文

引用来自“泥沙砖瓦浆木匠”的评论

看看我关于秒杀处理。博客

给个链接看看,我没有看见你的秒杀文章
泥沙砖瓦浆木匠
泥沙砖瓦浆木匠
看看我关于秒杀处理。博客
mysql并发insert死锁问题——gap、插入意向锁冲突

问题描述 线上出现MySQL死锁报警,通过show engine innodb status命令查看死锁日志,结合异常代码,还原发生死锁的事务场景如下: 环境: mysql5.7,事务隔离级别REPEATABLE-READ 表结构 并发...

hebaodan
2018/06/26
0
1
MySQL并发引起的死锁案例分析

在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下: 表结构如下: SQL语句如下: 原因分析MySQL的事务支持与存储引擎有关,MyISAM不支持事务,INNODB支持事务,更新时...

KingSirLee
2016/05/25
102
0
Mysql并发时经典常见的死锁原因及解决方法

Mysql并发时经典常见的死锁原因及解决方法 1. mysql都有什么锁 MySQL有三种锁的级别:页级、表级、行级。 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最...

rshare
2017/12/06
0
0
mysql事物锁等待超时,报错 Lock wait timeout exceeded; try restarting transaction

问题场景 问题出现环境: 1、在同一事务内先后对同一条数据进行插入和更新操作; 2、多台服务器操作同一数据库; 异常信息: mysqlexceptions.OperationalError: (1205, 'Lock wait timeout ...

aibati2008
2016/12/25
102
0
【MYSQL死锁问题】Deadlock found when trying to get lock;

问题: 在多访问的情况下,一个删除计划的操作会出现死锁现象,报错如下: 解决方案: 此删除涉及到事物,在删除计划的过程中,还要删除立项信息、合同需求信息关联的计划信息。在删除开始之...

卯金刀GG
2018/12/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Httpd 整合 Tomcat 步骤

环境:Tomcat8 + Httpd2.4 工作原理:借助于Tomcat的AJP连接器实现Apache与Tomcat的通信 配置步骤: 1. 配置httpd.conf 新增: Include conf/extra/mod_jk.conf 修改:添加 index.jsp <IfM...

ZeroneLove
昨天
1
0
Docker笔记3——容器命令(未写完,明天整理接着写)

未写完,明天整理接着写 新建并启动容器 docker run docker run [OPTIONS] IMAGE [COMMEND] [ARG...] OPTIONS: --name=[容器新名字] :为容器指定一个名称 -d:后台运行容器,并返回容器ID,...

HappyBKs
昨天
1
0
2018个人年终总结

感谢领导的信任和指导,新的一年获得了很多成长和提高,改掉了很多不好的习惯。 在这一年里,我在领导的帮助下,主要完成了以下功能: 1、完成上海银行版本投资营销相关功能的开发。 2、完成车...

万山红遍
昨天
9
0
保密工作与linux系统的发展

保密工作从性质上可以分成商业方面的保密和国家安全方面的保密。由于自己从事的是IT方面的工作,工作中必然会接触涉及到计算机信息方面的相关文件。加上单位已近通过武器装备科研生产单位二级...

linux-tao
昨天
2
0
Spark共享变量

概述 Spark程序的大部分操作都是RDD操作,通过传入函数给RDD操作函数来计算。这些函数在不同的节点上并发执行,但每个内部的变量有不同的作用域,不能相互访问,所以有时会不太方便,Spark提...

仟昭
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部