首页 > 数据库 >如何避免热度数据频繁更新造成数据库死锁?

如何避免热度数据频繁更新造成数据库死锁?

时间:2023-06-26 17:04:14浏览次数:52  
标签:事务 热度 数据库 索引 死锁 加锁 缓存

数据库死锁对业务来说是一个非常严重的问题,它一定一定一定是代码的执行流程处理不当造成的。


但是重构庞大的业务代码不是说了就能轻易做到的事情,下面给出了一些方案,由浅入深,告诉大家解决死锁问题的正确之道。





死锁问题产生的原因和条件





死锁问题一般发生在短时间内多个并发任务对同一组表进行修改的场景。


数据库在更新数据时会加锁,以确保不会发生并发写数据。


MySQL加锁的机制是根据索引情况加锁,可能是行锁,也有可能是间隔锁(详情可查看文档:https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html


并发修改表A时,只有一个请求能够获取到锁,其余的请求需要等待它处理完成释放锁,才能进行下一轮竞争。


如果此时获取到表A锁的线程T1同时需要修改表B,但表B的锁被线程T2获取,且T2正在等待表A的锁,这就造成了两个线程相互等待,进而死锁。




解决办法





1、给表增加索引


MySQL给表加锁时,锁的范围受索引影响。如果更新表时,where条件恰好有索引覆盖,那么MySQL可以精确地对满足条件的行记录加锁,而不会对一组范围内的数据(甚至是全表)加锁。

给需要更新的表添加索引,覆盖where条件里的字段,能够一定程度上缓解锁的碰撞概率,降低死锁发生次数。

2、使用主键更新表

这个办法与办法1的原理是相同的,也是利用索引让数据库精确地加锁。因为主键天然就是一个索引,所以不需要给表添加额外的索引。


3、缩短事务时长或取消事务

许多数据库框架或库都会提供事务管理机制,在默认情况下,它们采用AOP的方式来切入事务管理行为。

但是,这种事务管理行为是很粗糙的,并且会带来一个问题:如果方法执行的时间相当长,那么这个事务也会持续相当长的时间。事务越长也就意味着锁的碰撞概率越大。

如果开发人员对框架和库足够熟悉,并且对数据库事务有良好的理解,可以考虑手动控制事务,并采用编程式的事务管理方法,让应用程序在需要访问数据库的时候才开启事务。

或者,如果系统不强调瞬态一致性,也没有并发访问数据冲突,那么可以完全取消事务。

4、使用合理的编程范式

123方法只能缓解数据库表锁的碰撞概率,但不是解决死锁问题的根本之道。

死锁问题更深层次的原因是:应用程序无序地访问数据库,流程管控不合理。

一个清晰又整洁的编程范式,即可以有效提高代码的可读性,又可以降低数据库(以及外部服务)的访问次数,达到较高的程序效能。

//1.收集数据

var requiredData = queryFromDatabase()


//2.处理数据

process(requiredData)


//3.持久化处理后的数据

saveToDatabase(requiredData)


另外,尽量不要在循环里访问内数据库,在循环开始前收集所有必要的信息,在循环结束后统一持久化到数据库。


5、使用缓存处理热度数据


RMDB处理密集小事务的能力并不弱,但是如果并发处理的数据有重合,就会存在死锁的隐患。如果要解决RMDB在这方面的问题,就要投入不少精力,优化代码流程,精细化控制事务。


如果使用缓存来处理热度数据,可以巧妙地避开RMDB在这方面的缺陷。


缓存可以使用本地缓存,也可以使用分布式缓存,由系统的设计和架构决定。


6、其他方法


除了上面的5种方法,解决事务死锁问题的办法还有很多,例如:其他高级编程模型、特定的中间件支持,可以开放性思考。但是再多的优化技巧,也不如设计一个高效的程序结构。

标签:事务,热度,数据库,索引,死锁,加锁,缓存
From: https://blog.51cto.com/u_13561855/6555943

相关文章

  • 【直播预告】HarmonyOS极客松赋能直播第二期:数据库与网络连接开发
      ......
  • C# Winform通用开发框架,支持多语言,多数据库,自动更新,模块化
    C#Winform通用开发框架,支持多语言,多数据库,自动更新,模块化,可用其开发任意CS端系统,非常适合需要快速搭建项目的团队或个人使用。原创文章,转载请说明出处,资料来源:http://imgcs.cn/5c/661496079150.html......
  • MySQL 8.0原理与实战一网打尽,甲骨文数据库专家硬刚5年之作
    根据权威数据库技术排名网站DB-Engines今年4月的最新数据,MySQL是全球最流行的开源数据库,没有之一。在所有数据库排名中,MySQL仅次于Oracle,“屈居”亚军之位。但大家从截图中可以看出,MySQL与Oracle的得分差距已经非常小了。“开源壮年”数据库MySQL自1995年发布1.0版本以来,迄今已经走......
  • 8万中医药方剂数据库检索方剂大全ACCESS\EXCEL数据库
    今天这一份方剂数据库是最全也是最好的方剂数据库,不但字段内容多,而且记录数也是最多的,字段包含:名称、组成、出处、功效、主治、加减、用法用量、制备方法、临床应用、各家论述、用药禁忌、附注等。HTML内容字段是排版好了的全部内容截图下方有显示“共有记录数”,截图包含了表的所有......
  • java陷阱之数据库主从
    现象客户遇到工单缺少描述,查询日志写入描述报错,但那是工单又正常生产  原因先写入工单再查询工单实时性要求比较高的不能走从库,还有就是service层方法命名不规范,不点进去看根本不知道走从库,如果要走从库应该带上Slave后缀,查询缓存也一样带上cachefindProviderIdB......
  • 死锁面试题(什么是死锁,产生死锁的原因及必要条件)
    什么是死锁?所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。因此我们举个例子来描述,如果此时有一个线程A,按照先锁a再获得锁b的的顺序获得锁,而在此同时又有另外一个线程B,按照先锁b再锁a的顺序获得锁。......
  • Linux多线程10-死锁
    有时,一个线程需要同时访问两个或更多不同的共享资源,而每个资源又都由不同的互斥量管理。当超过一个线程加锁同一组互斥量时,就有可能发生死锁。两个或两个以上的进程在执行过程中,因争夺共享资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状......
  • NetCore使用使用Scaffold-DbContext命令生成数据库表实体类
    1.根据数据库生成实体类ModelsScaffold-DbContext"DataSource=.;InitialCatalog=TEST;UserID=sa;Password=pwd;TrustServerCertificate=True"Microsoft.EntityFrameworkCore.SqlServer-OutputDirModels-Force  2.根据数据表生成实体类ModelsScaffold-DbConte......
  • 产教融合,华为云GaussDB助推高校国产数据库课程建设 GaussDB数据库助推国产数据库高校
    近日,由教育部“数据科学课程群”虚拟教研室、中国计算机学会CCF长春分部主办,华为技术有限公司、高等教育出版社协办的教育部“数据科学课程群“虚拟教研室教学研讨会在长春顺利召开。会议集结了吉林大学、西安交通大学、中央民族大学、重庆大学、湖北民族大学、东北电力大学、吉林......
  • 从新手游上线看游戏数据库选型
    最近我们深入游戏场景,参与支撑一个全新的手游项目上线,交流中发现经验丰富的游戏架构师都比较认可一个观点:游戏业务设计离不开一款靠谱的KV数据库。这款游戏项目定位是爆款精品,有长期运营规划,因此在前期开发阶段就锁定了合适的“主数据库”选型——华为云KV数据库GaussDB(forRedis)......