数据库基本知识

感觉面试的时候面试官大多数都必问数据库,也可以理解,企业肯定会涉及到大规模数据存储,那么数据库存储就一定会用到数据库。做一些数据库相关的基本知识总结,持续更新~

【死锁专题】

1.如何解决数据库并发造成的安全问题(想让你说一些关于锁的知识)

        ①事务管理:使用数据库管理系统提供的事务管理功能。事务可以确保一组操作要么全部成功提交,要么全部失败回滚,从而保证数据的一致性和完整性

        ②加锁:使用适当的锁机制来控制并发访问。提供锁定数据行、表或其他资源,防止多个数据对同一资源进行修改,从而避免数据不一致性。

        eg:使用乐观或悲观并发控制机制,乐观并发控制通常基于版本控制或时间戳,允许多个事务同时读取数据,但写入时检查是否有冲突。悲观并发控制则是在访问数据时先获取锁,确保凄然事务无法修改。

        ③隔离级别:设置适当的事务隔离级别,以控制并发事务之间的可见性和影响范围。常见的隔离级别包括读未提交、读已提交、可重复读和串行化,可以根据应用需求选择。

        ④异常处理:编写异常处理模块抛出异常确保系统的稳定性和可靠性(这条说不说都行吧,感觉三条就够了)

2.数据库的死锁是什么

        加锁(Locking)是数据库在并发访问时保证数据一致性和完整性的主要机制。任何事务都需要获得相应对象上的锁才能访问数据,读取数据的事务通常只需要获得读锁(共享锁),修改数据的事务需要获得写锁(排他锁)。当两个事务互相之间需要等待对方释放获得的资源时,如果系统不进行干预则会一直等待下去,也就是进入了死锁(deadlock)状态。

3.如何解决死锁状态

        死锁不是数据库自身的问题,我们无法通过优化数据库配置来解决或者避免死锁,只能通过修改应用程序来解决。也可以捕获系统返回的死锁异常并在程序中加入重试机制。

4.常见的死锁原因与解决方案有:

        1. 事务之间对资源访问顺序的交替

        出现原因: 
        一个用户A 访问表A(锁住了表A),然后又访问表B;另一个用户B 访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这就死锁就产生了。

        解决方法: 
        这种死锁比较常见,是由于程序的BUG产生的,除了调整的程序的逻辑没有其它的办法。仔细分析程序的逻辑,对于数据库的多表操作时,尽量按照相同的顺序进行处理,尽量避免同时锁定两个资源,如操作A和B两张表时,总是按先A后B的顺序处理, 必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源

        2. 并发修改同一记录

        出现原因:主要是由于没有一次性申请够权限的锁导致的。参考:记录一次死锁排查过程

        用户A查询一条纪录,然后修改该条纪录;这时用户B修改该条纪录,这时用户A的事务里锁的性质由查询的共享锁企图上升到独占锁,而用户B里的独占锁由于A有共享锁存在所以必须等A释放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。这种死锁比较隐蔽,但在稍大点的项目中经常发生。 

        解决方法:

        a. 乐观锁,实现写-写并发

        b. 悲观锁:使用悲观锁进行控制。悲观锁大多数情况下依靠数据库的锁机制实现,如Oracle的Select … for update语句,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。

        3. 索引不当导致的死锁

        出现原因: 
        如果在事务中执行了一条不满足条件的语句,执行全表扫描,把行级锁上升为表级锁,多个这样的事务执行后,就很容易产生死锁和阻塞。类似的情况还有当表中的数据量非常庞大而索引建的过少或不合适的时候,使得经常发生全表扫描,最终应用系统会越来越慢,最终发生阻塞或死锁。

        另外一种情况是由于二级索引的存在,上锁的顺序不同导致的,这部分在讨论索引时会提到。参考:https://www.cnblogs.com/LBSer/p/5183300.html

        解决方法:

        SQL语句中不要使用太复杂的关联多表的查询;使用“执行计划”对SQL语句进行分析,对于有全表扫描的SQL语句,建立相应的索引进行优化。

5.如何尽量避免死锁

        1)以固定的顺序访问表和行。即按顺序申请锁,这样就不会造成互相等待的场面。

        2)大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。

        3)在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率。

        4)降低隔离级别。如果业务允许,将隔离级别调低也是较好的选择,比如将隔离级别从RR调整为RC,可以避免掉很多因为gap锁造成的死锁。

        5)为表添加合理的索引。如果不走索引将会为表的每一行记录添加上锁,死锁的概率大大增大。

补充,操作系统中的死锁:

 死锁产生的四个必要条件:互斥、请求与保持、不可剥夺、循环等待

预防死锁:除了不可以破坏互斥条件的三个破坏

避免死锁:银行家算法

        银行家算法,每一个新进程在进系统时,它必须申明在运行过程中,可能需要每种资源类型的最大单元数目,其数目不应超过系统所拥有的资源总量。当进程请求一组资源时,系统必须首先确定是否有足够的资源分配给该进程。如果有,再进一步运算将资源分配给该进程后,是否会使系统处于不安全状态。如果不会,才将资源分配给该进程。

参考文章:

数据库死锁及解决方法 - wezheng - 博客园 (cnblogs.com)

5 分钟理解数据库死锁_sql error: 1205, sqlstate: 40001-CSDN博客

计算机操作系统——死锁(产生的必要条件与处理死锁的四个关卡)_操作系统中必要条件请求与保持-CSDN博客

相关推荐

  1. 知识图谱数据库基本知识

    2024-06-07 09:36:08       22 阅读
  2. Web数据库基本知识,SQL基本语法

    2024-06-07 09:36:08       50 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 09:36:08       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 09:36:08       101 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 09:36:08       82 阅读
  4. Python语言-面向对象

    2024-06-07 09:36:08       91 阅读

热门阅读

  1. vue el-dialog封装成子组件(组件化)

    2024-06-07 09:36:08       26 阅读
  2. react-intl国际化在项目中的使用

    2024-06-07 09:36:08       29 阅读
  3. 浅谈人机交互

    2024-06-07 09:36:08       25 阅读
  4. 人机交互中的阴差阳错

    2024-06-07 09:36:08       25 阅读
  5. 解决nginx无法获取带下划线的header值

    2024-06-07 09:36:08       31 阅读
  6. 单双目视频转图片

    2024-06-07 09:36:08       24 阅读
  7. 常见排序算法,快排,希尔,归并,堆排

    2024-06-07 09:36:08       23 阅读
  8. Elasticsearch简介

    2024-06-07 09:36:08       27 阅读
  9. scss sass是什么?vue环境安装sass报错

    2024-06-07 09:36:08       24 阅读
  10. GUI guider 常用函数解析

    2024-06-07 09:36:08       19 阅读
  11. 洛谷 P3870 [TJOI2009] 开关 题解 线段树

    2024-06-07 09:36:08       29 阅读
  12. 【C++刷题】优选算法——前缀和

    2024-06-07 09:36:08       31 阅读