在两个或多个任务中,如果每个任务锁定了其他的任务试图锁定的资源,会造成这些任务永久阻塞,从而出现死锁。此时系统处于死锁状态。
死锁的原因:
在多用户环境下,死锁的发生是由于两个事物都锁定了不同的资源而又都在申请对方锁定的资源,即一组进程中的各个进程均占有不会释放的资源,但因相互申请其他进程占用的不会释放的资源而处于一种永久等待的状态。形成死锁有4个必要条件:
请求与保持条件:获取资源的进程可以同时申请新的资源。
非剥夺条件:已经分配的资源不能从该进程中剥夺。
循环等待条件:多个进程构成环路,并且其中每个进程都在等待相邻进程正在占用的资源。
互斥条件:资源只能被一个进程使用。
可能会造成死锁的资源:
每个用户会话可能有一个或多个代表它运行的任务,其中每个任务可能获取或等待获取各种资源。以下类型的资源可能造成阻塞,并最终形成死锁。
1.锁:等待获取资源的锁可能导致死锁。
2.工作线程:排队等待可用工作线程的任务可能造成死锁。
3.内存:当并发请求获取内存,而当前的可用内存无法满足其需求时,可能发生死锁。
4.并行查询执行的相关资源:通常与交换端口关联的处理协调器、发生器或者使用者线程至少包含一个不属于 并行查询的进程时,可能会相互阻塞,从而导致死锁。
减少死锁的策略:
1.在所有的事务中以相同的次序使用资源。
2.使事务尽可能简短并且在一个批次中。
3.为死锁超时参数设置一个合理范围,如3~10分钟;超时,则自动放弃本次操作,避免进程挂起。避免在事务内和用户进行交互,减少资源的锁定时间。
4.使用较低的隔离级别,相比较高的隔离级别能够有效的减少持有共享锁的时间,减少锁之间的竞争。
5.使用Bound Connections。Bound Connections 允许两个或多个事务连接共享事务和锁,而且任意一个事务连接都要申请锁如同另一个事务要申请锁一样,因此可以运行这些事务共享数据而不会有加锁冲突。
6.使用基于版本控制的隔离级别。持快照事务隔离和指定READ_COMMITTED隔离级别的事务使用行版本控制,可以将读写操作之间发生死锁的几率降至最低。