什么是数据库死锁?
两个或以上事务同时对一批资源占用锁,并形成循环,就会造成事务死锁,一般报错如下:
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
1 插入场景:(user_id和pool_id是联合唯一索引)
场景:有一个job,定时会查出一批数据,然后分页,每页一千条数据批量插入数据库中,伪代码如下:
---------------------
int totalRow = xxxMapper.count();
for (int page=0; page <= totalRow/pageSize; page++) {
    List<Xxx> data = xxxMapper.selectByPage(page * pageSize, pageSize);  // 这里分页可用上一次的最大id,用偏移量只是方便理解
    if (CollectionUtils.isNotEmpty(data)) xxxMapper.batchInsert(data);
}
---------------------
上面没有开一个统一的事务,所以每次batchInsert()都是一次独立新的事务,多次独立事务批量插入,并且user_id和pool_id是联合唯一索引当时就发现如下问题:
### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
### SQL: insert into leads_distribution_pool ( user_id, pool_id ) values ( ?,         ? ) ,  ( ?,         ? );
- 产生原因分析(IK等待NK,而不同事务之间的NK又会相互等待RK导致的):
在分批插入中,事务A会先申请对应行记录(假设是1,2,3)的行锁X RK(排他 行级锁),然后事务B也会申请对应行记录(假设是4,5,6)X RK. 这时候事务A他需要插入,会先申请一个X IK(排他 插入意向锁),因为X IK是需要获取S NK锁(共享 next-key锁),但是由于事务B对4,5,6加了X RK,所以事务A的next-key锁里面的间隙锁无法对1,2,3周围的间隙如4加一个锁,这时候事务A就获取S NK锁失败,导致无法获取X IK锁,同理事务B也是这种,由于事务A的X NK阻塞,导致获取插入意向锁也失败,这样就会形成一种相互等待的状态,从而导致死锁。
- 解决方案:
-- 第一种:给批量插入加一个redis锁,处理完一个在处理下一个批量插入
-- 第二种:降低隔离级别,比如把隔离级别变为可提交读(Innodb中S NK和X IK是Innodb可重复度级别才有)
2 更新场景:(teacher_oa_id是普通索引,id是主键索引)
- 原来的SQL:update user set hujin_wx_id = 121 WHERE teacher_oa_id = #{oaId}
- 改造后的SQL:update user set hujin_wx_id = 121 WHERE id = #{id}
区别就是原来的用了两个索引,而innodb中的行级锁是锁索引的,先会锁住非主键索引,再根据非主键索引找到主键索引,然后把主键索引锁住。
问题就在这里,假设有另一个sql是:update user set teacher_oa_id = #{oaId}  WHERE id = #{id},这样就先锁住主键索引,然后更新teacher_oa_id需要获取这个非主键索引的行级锁,然后这时候由于另一条sql已经锁住teacher_oa_id索引了,这时候这条sql想去锁teacher_oa_id索引就失败了。然后原来的sql等待id主键索引的锁,另一个sql等待teacher_oa_id的索引.解决办法:将oaId改成用id来查找,这样直接找主键索引就不会死锁冲突。
更新死锁文章:https://blog.csdn.net/guanfengliang1988/article/details/80356648
批量插入死锁文章:https://blog.csdn.net/qq_16681169/article/details/73359670

数据库死锁产生原因及场景相关推荐

  1. 数据库--死锁产生原因及解决方法

    数据库与操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据时,就会产生多个事务同时存取统一数据的情况.如果对并发操作没有相应的控制就可能会导致读取和存储不正确的数据,破坏了数据库的一致 ...

  2. 数据库:分享六个 MySQL 死锁案例,能让你理解死锁的原因!

    正文 最近总结了一波死锁问题,和大家分享一下,我这也是从网上各种浏览博客得来,希望原作者见谅,参考博客文末下方. Mysql 锁类型和加锁分析MySQL有三种锁的级别:页级.表级.行级. 表级锁:开销 ...

  3. 关于oracle数据库死锁的解决 以及产生的原因

    前段时间写sql语句事物造成了数据库死锁,导致所有更新操作无法执行 1.查死锁 查看关于锁的会话信息 select * from v$session t1, v$locked_object t2 wh ...

  4. 数据库死锁原因及解决办法(全)

    死锁(Deadlock) 所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互 ...

  5. 数据库死锁常见场景以及排查解决方案

    死锁的概念 死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁 ...

  6. mysql 秀出两个相关联的表中满足条件的内容_这六个 MySQL 死锁案例,能让你理解死锁的原因!...

    点击蓝色"架构文摘"关注我哟 加个"星标",每天上午 09:25,干货推送! 来源:王啸tr1912  |  https://blog.csdn.net/tr1 ...

  7. 一次诡异的数据库死锁问题排查过程

    GitHub 1.8k Star 的Java工程师成神之路 ,不来了解一下吗? GitHub 1.8k Star 的Java工程师成神之路 ,真的不来了解一下吗? GitHub 1.8k Star 的 ...

  8. 一次诡异的数据库死锁问题排查过程 1

    GitHub 1.8k Star 的Java工程师成神之路 ,不来了解一下吗? GitHub 1.8k Star 的Java工程师成神之路 ,真的不来了解一下吗? GitHub 1.8k Star 的 ...

  9. 研发协同平台数据库死锁处理及改进

    源宝导读:数据库死锁是高并发复杂系统都要面临课题,处理死锁问题没有一招制敌的标准方法,需要具体问题具体分析.本文将基于研发协同平台遇到的死锁案例,介绍从监控.分析到处理的完整过程和经验总结. 一.背景 ...

最新文章

  1. 智能跳过节假日算法java_java计算两个日期之前的天数实例(排除节假日和周末)...
  2. FreeBSD Top States
  3. idea 配置多个jdk
  4. 单片机位寻址举例_单片机的寻址方式
  5. 『Spring.NET+NHibernate+泛型』框架搭建之DAO(三)★
  6. canopy算法流程_Canopy聚类算法
  7. WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[上篇](转)...
  8. LeetCode 357. 计算各个位数不同的数字个数(动态规划)
  9. Waiting Processed Cancelable ShowDialog (Release 2)
  10. 【业余无线电BI1FKP】宝峰UV9R-Plus写频、自制写频线
  11. 手机端app存取session问题(tp5框架)
  12. Golang 内建类型和内建函数 builtin包 注释翻译
  13. Scrum立会报告+燃尽图(十月二十七日总第十八次)
  14. 如何看懂这些图形学公式
  15. 与小卡特一起学python 第18章 一种新的输入-事件
  16. Tmux Cheat Sheet
  17. dlib疲劳检测_dlib库检测人脸使用方法与简单的疲劳检测应用
  18. GSMA SGP.21协议学习
  19. 男人四十一枝花,我花开后百花杀!Orz..繁忙的工作之余,joke一下~~
  20. MySQL 排错-解决MySQL非聚合列未包含在GROUP BY子句报错问题

热门文章

  1. 江湖终于承认, 我是正房
  2. Vue.js——60分钟组件快速入门(下篇)
  3. 如何把pdf转换成word转换器在线
  4. ajax函数返回值,ajax:怎么获得onreadystatechange调用的函数的返回值?
  5. java中反爬虫_反网络爬虫策略(转自Javaeye)
  6. python psutil模块查找进程_python模块 - psutil
  7. AttributeError: ‘LoginPage‘ object has no attribute ‘driver‘
  8. POJ - 3252二进制数位DP
  9. 数据中心网络400G硅光光模块技术方案浅谈
  10. Unity Addressable内存管理