SQL Server死锁和数据页

时间:2014-07-15 20:12:50

标签: sql sql-server

  1. 如果在对该行进行某些修改(更新查询)时锁定了表中的行(没有主键),我假设首先在表上获取意图锁,然后在独占之前页在行上获得锁定。

    现在让我们说其他一些线程希望同时对同一个表中某些其他行进行修改(更新查询) ,然后SQL Server抛出以下错误:

      

    Msg 1205,Level 13,State 45,Line 1   事务(进程ID 65)在锁资源上与另一个进程发生死锁,并被选为死锁牺牲品。重新运行该交易。

    现在这个错误可能是同一个表的其他行在第一个查询的同一数据页中锁定的数据中的原因吗?

  2. 我知道数据页面还会选择我们不要求的其他数据。因此,如果我们在表中有主键,那么数据页仍会选择其他数据或仅选择具有主键的那一行吗?

4 个答案:

答案 0 :(得分:1)

SQL Server中有多种锁,用于不同的"粒度"数据。

在一个完美的世界中,如果你只更新一行,它实际上只能保持行锁定而其他任何行都不会被锁定。

发动机保留升级"的权利。锁定更大的集合,例如页面甚至整个表格 如果您要更新范围,则可能需要这样做。

如果您说您的主键也可能是您的聚簇索引键。并且它是找到要更新的行的标准...当然,您可能总是避免锁定太多行 除非您在表格中定义了任何其他索引 然后,您可能会对可能导致死锁的存储单元产生影响。

-

要理解为什么看到更改,请记住在SQL Server中,表只是逻辑实体,而索引是" real"表。

如果你根本没有索引,那么db引擎可能别无选择,只能一直锁定整个表,因为它没有基础只锁定一系列行的基础。
它需要一个相关的索引来创建锁 - 并且备用其他行。

一旦你可以说你想要更新密钥,例如" 1到5",那么db引擎可以定义这些密钥值的锁。 然后表的其余部分没有锁定!

答案 1 :(得分:1)

  
      
  1. 可能是同一个表的另一行是在第一个查询的同一数据页中锁定的数据之间的原因吗?
  2.   

没有。如果两个查询都使用相同的粒度(例如,行),那么它们将获得高级别(表(分区),页面)和低(行)级别的不同锁定的兼容意图锁。即使它们使用不兼容的粒度,也不会发生死锁。可能会发生阻塞,但没有死锁。

  

我知道数据页面还会选择我们不要求的其他数据。因此,如果我们在表中有主键,那么数据页仍然会选择其他数据或仅选择具有主键的那一行吗?

这没有任何意义。您正在将逻辑(主键)与物理(数据页面)混合在一起,而data page also selects additional data that we do not request for根本无法为我解析。我只能推测你试图说的是:

  

在组织为堆(无聚集索引)的表中,所有扫描都必须检查每一行以测试谓词。这将导致锁定冲突。

当堆上发生并发更新(没有聚簇索引的表)时如果没有要考虑的非聚簇索引那么没有更新可以死锁。所有更新都将以相同的顺序扫描表(堆物理分配顺序),并且将以相同的顺序获取所有锁。更新可以阻止,但不会死锁。

当组织为聚簇索引的堆或表上发生并发更新时,但是存在非聚簇索引,然后每个更新可以使用一个(或多个)非聚簇索引来定位更新的候选行。不使用相同谓词的更新(即不同的WHERE子句)可以使用不同的NC索引,顺序不同。这些可能会死锁,因为获取锁的顺序会有所不同。

当组织为聚簇索引的表上发生并发更新时,会发生 死锁,因为应用程序可以按照导致死锁的顺序显式请求更新(Tran 1在Tran时更新键A然后更新2更新密钥B然后A)。

死锁可以发生的方式还有很多,但这些是UPDATE和UPDATE死锁可能发生的基本方式。

如果您想在SQL Server always start by capturing the deadlock graph中获得有关死锁,任何死锁的答案。没有死锁信息,一切都在猜测。

PS。请不要将群组有组织的表格称为'主键'。主键是一个逻辑概念。

答案 2 :(得分:0)

这不是一件容易回答的事情,因为多件事可能会导致死锁,并且在不同的时间可能会有所不同。调查imo的最佳方法是使用SQL Server配置文件并查找死锁事件并捕获死锁图from MSDN。这个article包含有关SQL Server如何锁定的完整详细信息,以及有关死锁和死锁避免的一些其他信息。

回答你的问题:

  1. 是的,这两行可能是死锁等待(转换死锁)
  2. 取决于您的查询要求的内容。每个查询都指定它想要的列,因此在您的控件中。如果你只要求PK,那就是你将获得的。

答案 3 :(得分:0)

这两个进程想要访问由另一个进程锁定的资源并相互阻塞。

以下博客介绍了死锁预防:

http://www.sqlusa.com/bestpractices/deadlock/