03.05 数据库什么时候会产生死锁?

赵佳鑫15769579117


不锁怕出事,锁了又怕锁死了!!!

数据库由于数据存储速度快,数据稳定,结构化的特性,被广泛用作数据存储,并成为最重要,最常见的方式!

数据库从20世纪50年代诞生伊始,就因为支持事务的特性得到大力的发展,最终各种数据库诸如oracle,Sybase,mysql等关系型数据库百花齐放,既然数据库是因为事务而生,那么事务的特性又是哪些呢?简而言之就是ACID(原子性,一致性,隔离性,持久性)!


而为了保持数据的一致性,数据库都有了一个操作叫做加锁!有表级锁,行级锁,页面锁!

死锁就是说两个线程在争同一个资源,然后互不相让,导致锁死的情况(比如两个人从两端走上独木桥,然后卡死在桥中间)!

回到问题本身,数据库在什么时候会产生死锁呢?

1,情况一:我中有你,你中有我!

事务一:两个操作update A;update B;

事务二:两个操作update B;update A;

线程一执行事务一到一半的时候,锁了A想要获得B的锁,与此同时事务二执行到了锁B,想要获得锁A的时候,因为互相都想要对方拥有的锁,而导致死锁!

2,情况二:吃着碗里的,看着锅里的!

A线程先查询了一条记录(使用了共享锁),与此同时B线程正要修改这条记录(使用了独占锁),然后A线程突然想修改这条记录了,怎么办呢?升级锁。。而B线程想要降级为共享锁,必须要等到A线程释放掉共享锁,这样就形成了死锁!

可以看到这个过程中是A占着共享锁想要升级,B占着独占锁想要降级,然后卡死!

3,牵一发而动全身!

一个表结构,必须要有适当的索引等优化手段,如果在执行事务的时候,没有加索引条件甚至没有任何条件,那么将执行全表扫描,如果是多个事务在操作,很容易就发生了阻塞和死锁!所以字段加索引非常重要!!


可以说数据库死锁必然会造成很严重的生产事故,所以要尽量避免死锁的发生,而如何避免呢?我会在后面的回答中逐一解答,敬请关注。。。


此生唯一


数据库是一个软件,是一个很多用户会一起使用的软件。

当多个用户同时的去操作数据库中数据的时候,在数据库中就会产生多个用户去存取同一条数据的情况。如果两个或多个以上的用户在执行的过程中,因争夺资源导致互相等待,并且将一直等待下去,这种情况叫做死锁。


产生死锁的条件

  • 一条数据每次只能被一个用户使用。

  • 一个用户请求资源阻塞时,对已经获得的资源保持不放

  • 用户已经获得的资源,未使用前,别人不能抢走

  • 几个用户形成首尾相接的循环等待资源

几个条件同时发生的时候,就会产生思索。


比如小明和小红都要做饭,做饭需要铲子和锅(加入铲子和锅各有一个)。

小明拿到了铲子,准备去找锅。

小红拿到了锅,准备去找铲子。

然后他/她俩就僵持住了,每个人都拿着手上的东西不放手,于是就一直僵持下去了。

数据库锁类型

  • 排它锁(X锁):锁上之后,其他用户不能对其查询和修改。

  • 共享锁(S锁):锁上之后,其他用户可以查询,但是不能修改。


常见的产生死锁的原因

  • 对相同的资源,访问顺序不相同:这个好理解吧,上面那个例子就是这个问题。小明做饭先找铲子后找锅,小红做饭先找锅后找铲子。解决的方法也比较简单,就是让他们的顺序保持一致就好了。

  • 索引失效:有时候索引失效导致查询进行了全表扫描,执行全表扫描,会把行级锁上升为表级锁,如果这样的事情发生次数太多,就很容易导致死锁。解决方法也很简单啦,别让索引失效就好了。产生索引失效的原因也有很多,之前我有介绍过。

  • 并发修改同一记录:用户A先查询一条数据,上了共享锁,这时候用户B要修改数据,上了独占锁,赖好不好的,A也要做数据修改了,那么共享锁企图上升为独占锁。这时候,用户B的独占锁要等着A释放共享锁,但是A要做锁升级,还必须等待B释放独占锁,于是出现了死锁。数据库解决这种问题,引入了悲观锁和乐观锁。这里就不展开来说了。


希望我的回答能够帮助到你!


分享到:


相關文章: