感觉面试的时候面试官大多数都必问数据库,也可以理解,企业肯定会涉及到大规模数据存储,那么数据库存储就一定会用到数据库。做一些数据库相关的基本知识总结,持续更新~
【死锁专题】
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. 索引不当导致的死锁
出现原因:
如果在事务中执行了一条不满足条件的语句,执行全表扫描,把行级锁上升为表级锁,多个这样的事务执行后,就很容易产生死锁和阻塞。类似