关于SQL Server中的死锁详解介绍(1/3)

 一些基础知识
    要理解SQL Server中的死锁,更好的方式是通过类比从更大的面理解死锁。比如说一个经典的例子就是汽车(主体)对于道路(资源)的征用,如图1所示。

对于死锁的直观理解

     在图1的例子中,每队汽车都占有一条道路,但都需要另外一队汽车所占有的另一条道路,因此互相阻塞,谁都无法前行,因此造成了死锁。由这个简单的例子可以看出,发生死锁需要四个必要条件,如下:

1)互斥条件:

    主体对于资源是独占的,图1中每条汽车道只能跑一队汽车,不能跑第二队。

 2)请求和等待条件:

     指主体已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它主体占有,此时请求主体阻塞,但又对自己已获得的其它资源保持不放。在图1中,每队汽车已经占有了一条车道,又想获得另一条由其它车队占有的车道,造成阻塞。

 3)不剥夺条件

    指的是主体已经获得的资源在完成其目标之前不能被释放。在图1中,目标指的是汽车可以通过车道,不剥夺指的是在完成这个目标之前,车队并不会让出其已占的车道。

 4)环路等待条件

    指在发生死锁时,必然存在一个主体——资源的环形链,即主体集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。在图1中可以看出,四条车道和四队汽车正好符号环路等待的条件,车队1希望获得车队2占有的车道,车队2希望获得车队3占有的车道,车队3希望获得车队4占有的车道,车队4反过来又希望获得车队1占有的车道,形成一个环路。

 死锁在进程中的定义
    下面让我们再缩小死锁的范围,回到计算机的世界。在计算机中,主体的这个抽象的词被更具体的进程所替代,而资源缩小到计算机所使用的资源。在计算机中,死锁是由阻塞所引起。因此在开始之间,我想简单介绍一下进程的几种状态,如果有兴趣,也可以参看我之前的一篇文章:http://www.cnblogs.com/CareySon/archive/2012/05/04/ProcessAndThread.html.

    简单来说,进程是组织资源的最小单位,多道操作系统中允许并发进行,每一道进程都像图1所示的汽车那样,需要前进,在前进的过程中,需要各种资源以及CPU,图2是不考虑进行创建销毁等状态,简单概述进程的几种状态。

   

.进程的几种状态

 

    很多资源是可以共享的,比如内存。但对于打印机等资源来说就需要独占。图2中的几种状态简单理解是,当进程没有所需的资源时,比如说等待IO,等待打印机,这时是阻塞状态。而当进程获得了这些资源时,就可以变为就绪状态,在就绪状态的进程再获得CPU时,就变为执行状态。而执行的过程中,CPU被剥夺了就继续变为就绪状态,或是当需要其它资源时,就会继续变为阻塞状态。以此往复。

    在操作系统中,有些资源可以是不可剥夺资源,比如打印机,当打印机被一个进程占用时,另一个进程就会被阻塞。还有一类资源是要重点强调的,这类资源是临时性资源,比如进程产生的信号量,消息,缓冲区内的消息,多个进程或线程访问这类资源时更容易引起死锁。在SQL Server中产生的死锁其实就是由这类资源所造成的。

    当两个或多个进程既然有了当前的资源,又需要额外的资源时,满足了上面所述死锁的四个条件时,就会产生死锁。

 死锁在SQL Server中的定义
     在SQL Server中,阻塞更多的是产生于实现并发之间的隔离性。为了使得并发连接所做的操作之间的影响到达某一期望值而对资源人为的进行加锁(锁本质其实可以看作是一个标志位)。当一个连接对特定的资源进行操作时,另一个连接同时对同样的资源进行操作就会被阻塞(当然了,这和锁之间的兼容性有关,关于锁更深入的讨论超出了本文的范围,关于这部分内容可以看我的另一篇文章:T-SQL查询进阶—理解SQL Server中的锁),阻塞是死锁产生的必要条件。

    下面,我们通过一个简单的例子来看死锁。

     首先,要出现死锁,一定要满足前面提到死锁出现的四个必要条件,图3中可以清楚的看到这两个连接(SPID52和SPID55)是如何满足这四个条件的。

  

Lock Monitor
    图3中死锁后可以看到,SQL Server并不会让死锁僵持下去,而是通过一个叫Lock Monitor的线程定期进行检测(默认是5秒)。当发现死锁后,会剥夺其中一个SPID占有的资源,好让另一个SPID执行下去,具体剥夺哪一个SPID基于如下两个因素:

 1.死锁的优先级。

    2.在死锁优先级相同的情况下,根据开销,开销小的事务将会被剥夺

 

    下面,还是根据图3中的例子,我们设置死锁优先级,使得左边的事务被剥夺回滚,如图4所示。

   

.设置死锁优先级后,优先级低的SPID被剥夺

 

SQL Server中死锁的检测
    首先要理解,在多并发的环境中,死锁是不可避免的,只能尽量的通过合理的数据库设计,良好的索引,适当的查询语句以及隔离等级来尽量的减少。因此,检测死锁的目的是知道哪里可能会产生死锁,通过对检测到的死锁进行分析后,尽量的优化查询/索引/隔离等级来降低死锁发生的可能性。

    查看死锁有两种方式,一种是通过服务端的Trace来做,另一种是通过SQL Profiler,首先让我们来看通过Trace来抓死锁。

 

首页 1 2 3 末页

时间: 2024-08-01 12:36:50

关于SQL Server中的死锁详解介绍(1/3)的相关文章

SQL Server 事务隔离级别详解

原文:SQL Server 事务隔离级别详解 标签: SQL SEERVER/MSSQL SERVER/SQL/事务隔离级别选项/设计数据库事务级别 SQL 事务隔离级别 概述      隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一定的影响作用. 步骤 事务隔离级别通过影响读操作来间接地影响写操作:可以在回话级别上设置事务隔离级别也可以在查询(表级别)级别上设置事务隔离级别.事务隔离级别总共有6个隔离级别:READ UNCOMMITTED(未提交读,读脏),相当于(NOL

SQL Server事务隔离级别详解

SQL Server事务隔离级别详解 标签: SQL SEERVER/MSSQL SERVER/SQL/事务隔离级别选项/设置数据库事务级别 SQL 事务隔离级别 概述      隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一定的影响作用. 步骤 事务隔离级别通过影响读操作来间接地影响写操作:可以在回话级别上设置事务隔离级别也可以在查询(表级别)级别上设置事务隔离级别.事务隔离级别总共有6个隔离级别:READ UNCOMMITTED(未提交读,读脏),相当于(NOLOCK)

SQL Server CHARINDEX和PATINDEX详解

server|详解 SQL Server CHARINDEX和PATINDEX详解        假如你写过很多程序,你可能偶尔会碰到要确定字符或字符窜串否包含在一段文字中,在这篇文章中,我将讨论使用CHARINDEX和PATINDEX函数来搜索文字列和字符串.我将告诉你这两个函数是如何运转的,解释他们的区别.同时提供一些例子,通过这些例子,你可以可以考虑使用这两个函数来解决很多不同的字符搜索的问题.        CHARINDEX和PATINDEX函数常常用来在一段字符中搜索字符或者字符串.

SQL SERVER分区具体例子详解

原文:SQL SERVER分区具体例子详解 在日常工作中,我们会遇到以下的情况,一个表每日数万级的增长,而查询的数据通常是在本月或今年,以前的数据偶尔会用到,但查询和插入的效率越来越慢,用数据库分区会有助于解决这个问题.关于分区的理论知识网上很多我这里就不在累赘,我从一个实际例子出发,看如何将一个已经运行了很长时间的普通表进行分区. 提出问题 需解决问题:有一个数据表数据很大,我们通常的查询是在一个季度中.我们需要将以往年份的数据按不同年份存在文件组里,当年的数据分为4个季度存,如果到了新的一年

SQL Server中追踪器Trace的介绍和简单使用

原文:SQL Server中追踪器Trace的介绍和简单使用 一.What is Trace? 对于SQL Profiler这个工具相信大家都不是很陌生,没用过的朋友可以在SQL Server Management Studio>工具>SQL Server Profiler处使用.这个工具是用来监控SQL,存储过程的执行,用户登录等等信息.但这个工具只是一个GUI,他的本质就是Trace.下面是Trace的架构:    数据库引擎会产生一系列事件,然后各个trace可以去订阅自己感兴趣的事件,

SQL Server 事务和锁详解

最近在项目中进行压力测试遇到了数据库的死锁问题,简言之,如下的代码在 SERIALIZABLE 隔离级别造成了死锁:  代码如下 复制代码 SELECT @findCount=COUNT(id) FROM MyTable WHERE [fk_related_id]=@Argument IF (@findCount > 0) BEGIN ROLLBACK TRANSACTION RETURN ERROR_CODE END INSERT INTO MyTable ([fk_related_id],-

Microsoft SQL Server数据库开发问题详解

我要强调的是,从技术角度来说,不使用T-SQL来编写存储过程是可能的.那么有没有理由这么做呢?一种情况就是这是一个用来从普通文件或者网络服务中检索数据的CLR存储过程,并将数据格式设置为行集.这里可能就会用到不需要T-SQL的操作--但是这并不是对T -SQL存储过程能力的一个很好的比喻. 1.SQL Server 2005中的存储过程并发问题 问:我在SQL Server2005中遇到了并发问题.我持有车票的公共汽车上有一些空闲的座位.我在插入销售的查票之前,需要查看是否还有空闲的座位.我的存

SQL SERVER 日期格式转换详解_Mysql

SQL SERVER 2000用sql语句如何获得当前系统时间就是用GETDATE(); Sql中的getDate()2008年01月08日 星期二 14:59Sql Server 中一个非常强大的日期格式化函数 复制代码 代码如下: Select CONVERT(varchar(100), GETDATE(), 0);-- 05 16 2008 10:57AMSelect CONVERT(varchar(100), GETDATE(), 1);-- 05/16/08Select CONVERT

SQL Server比较常见数据类型详解_MsSql

   在SQL Server 中每个变量.参数.表达式等都有数据类型.系统提供的数据类型分为几大类,如表4-2 所示.     其中,BIGINT. SQL_VARIANT 和TABLE 是SQL Server 2000 中新增加的3 种数据类型.下面分类讲述各种数据类型. 一. 整数数据类型     整数数据类型是最常用的数据类型之一.     1.INT (INTEGER)         INT (或INTEGER)数据类型存储从-2的31次方 (-2 ,147 ,483 ,648) 到2