数据库是一个软件,是一个很多用户会一起使用的软件。
当多个用户同时的去操作数据库中数据的时候,在数据库中就会产生多个用户去存取同一条数据的情况。如果两个或多个以上的用户在执行的过程中,因争夺资源导致互相等待,并且将一直等待下去,这种情况叫做 死锁 。
产生死锁的条件
- 一条数据每次只能被一个用户使用;
- 一个用户请求资源阻塞时,对已经获得的资源保持不放;
- 用户已经获得的资源,未使用前,别人不能抢走;
- 几个用户形成首尾相接的循环等待资源。
几个条件同时发生的时候,就会产生死锁。
比如小明和小红都要做饭,做饭需要铲子和锅(假如铲子和锅各有一个)。
- 小明拿到了铲子,准备去找锅;
- 小红拿到了锅,准备去找铲子;
- 然后他/她俩就僵持住了,每个人都拿着手上的东西不放手,于是就一直僵持下去了。
数据库锁类型
- 排它锁(X锁):锁上之后,其他用户不能对其查询和修改。
- 共享锁(S锁):锁上之后,其他用户可以查询,但是不能修改。
常见的产生死锁的原因
- 对相同的资源,访问顺序不相同:这个好理解吧,上面那个例子就是这个问题。小明做饭先找铲子后找锅,小红做饭先找锅后找铲子。解决的方法也比较简单,就是让他们的 顺序保持一致 就好了。
- 索引 失效:有时候索引失效导致查询进行了全表扫描,执行全表扫描,会把行级锁上升为表级锁,如果这样的事情发生次数太多,就很容易导致死锁。解决方法也很简单啦,别让索引失效就好了。产生索引失效的原因也有很多,之前我有介绍过。
- 并发修改同一记录:用户A先查询一条数据,上了共享锁,这时候用户B要修改数据,上了独占锁,赖好不好的,A也要做数据修改了,那么共享锁企图上升为独占锁。这时候,用户B的独占锁要等着A释放共享锁,但是A要做锁升级,还必须等待B释放独占锁,于是出现了死锁。数据库解决这种问题,引入了 悲观锁和 乐观锁 。这里就不展开来说了。