SQL Server - [SELECT]锁定[UPDATE]吗?

时间:2012-08-06 13:44:21

标签: sql sql-server performance sql-server-2005 locking

我有一个复杂的选择查询和一个巨大的表。

我正在运行此select语句,同时Update语句到达并尝试更新表。

恕我直言 - 更新需要独占锁 - 因此更新语句必须等待,直到select命令完成。

  1. 我是对的吗?

  2. 我该怎么做才能:执行复杂select也让update命令运行(目前我没有关心脏数据

2 个答案:

答案 0 :(得分:15)

是 - 在某种程度上。

SELECT持有共享锁的时间取决于事务的隔离级别:

  • READ UNCOMMITTED - 根本没有获取共享锁定 - UPDATE未被阻止
  • READ COMMITTED - 仅在读取数据期间获取共享锁定 - UPDATE可能会在很短的时间内被阻止
  • REPEATABLE READSERIALIZABLE - 获取并保留共享锁,直到交易结束 - UPDATE被阻止,直到SELECT交易结束

从技术上讲,UPDATE语句首先得到一个UPDATE锁 - 它与共享锁(由SELECT使用)兼容 - 在读取时持续一段时间要更新的行的当前值。

完成后,Update锁将升级为独占锁,以便将新数据写入表中。

答案 1 :(得分:5)

当您同时运行两个语句(SELECT和UPDATE)时,实际行为基本上是随机的。这是因为这两种操作都不是即时的。为简化起见,请将表视为列表,SELECT正在遍历此列表,一次查看一行。 UPDATE还尝试更新一行或多行。当UPDATE尝试更新后面的行时,SELECT然后没有任何事情发生(没有阻塞),因为SELECT已经超过了UPDATE点。如果UPDATE正在尝试更新SELECT正在查看的行,那么UPDATE将不得不等待SELECT继续前进,这将非常非常快地发生并且UPDATE将取消阻止并成功, SELECT正在向前发展。但是,如果UPDATE正在更新SELECT的提前行,那么更新将成功,并且稍后,SELECT将最终到达此行并将停止,阻止。现在SELECT必须等待,直到执行UPDATE的事务提交

这是简化的故事。现实生活要复杂得多。 SELECT可以有多个读取点(并行计划)。 SELECT和UPDATE都需要选择访问路径,这意味着使用一个或多个辅助索引来定位行。复杂查询可能包含导致多次查找表的运算符(例如,连接)。 SELECT和UPDATE都可以进行书签查找以获取BLOB数据,这会显着改变锁定行为。基数估计可能导致SELECT以高粒度锁定模式运行(例如,表级共享锁)。 UPDATE可以触发锁升级,升级可能会失败或成功。 Choosing different access paths can lead to deadlockFalse lock contention can occur due to hash collisions。只有一个无数变量在这里有发言权。我甚至没有提到更高的隔离级别(可重复读取,可序列化)。

也许您应该使用SNAPSHOT隔离并停止担心此问题?