SQL服务器 - 不[选择]锁[更新]?(SQL Server - does [SELECT] lo

2019-06-26 19:31发布

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

我跑这个select语句,同时一个Update语句到达并尝试更新表。

恕我直言-更新需要排它锁-这样的更新语句将不得不等待 ,直到选择命令完成。

  1. 我对吗 ?

  2. 我该怎么才能做到:执行复杂的select 也让update命令运行( 目前我不在乎脏数据

Answer 1:

是 - 在一定程度上。

一多久SELECT持有的共享锁取决于事务的隔离级别:

  • READ UNCOMMITTED -没有共享锁被获取在所有- UPDATE没有被阻塞
  • READ COMMITTED -共享锁获取只是为了读取数据的持续时间- UPDATE可能被阻塞的时间很短的时间
  • REPEATABLE READSERIALIZABLE -共享锁被获取并保持到直至事务结束- UPDATE被阻塞,直到SELECT事务端

从技术上讲, UPDATE语句第一得到一个UPDATE锁-其为具有共享锁(如所使用的兼容SELECT ) -供的,而它的读取行的电流值将被更新的时间的持续时间。

一旦这样做了,将Update锁升级为独占锁定为新的数据写入到表中。



Answer 2:

当你同时运行两个语句(一个SELECT和UPDATE)的实际行为将基本随机的。 这是因为无论是操作的是瞬发。 为了简化,考虑你的表中的列表并选择遍历该列表,每次看着一行。 更新也试图更新一行或多行。 当更新试图更新背后的SELECT则什么也不会发生(不阻止)一行,因为SELECT已经发展过更新点。 如果更新试图更新在其SELECT期待,现在该行则更新将不得不等待选择继续前进,这将发生非常非常非常快,更新将解锁并取得成功, 选择正在向前推进。 但是,如果更新是提前选择的更新一行,则更新会成功,以及后来的SELECT最终将完全达到该行并停止,阻止。 现在选择要等到该做的UPDATE事务提交

这是简单的故事。 在现实生活中要复杂得多。 该SELECT可以有多个读取点(并行计划)。 无论是SELECT和UPDATE受到选择的访问路径,这意味着使用一个或多个二级索引定位行。 复杂的查询可能包含导致多个查找到一个表(例如,连接)运算符。 无论是SELECT和UPDATE可以做书签查找获取BLOB数据,这显著改变锁定行为。 基数估计可能导致SELECT以高粒度锁定模式(例如,表级共享锁)上运行。 更新可以触发锁升级,并且升级可能会失败或成功。 选择不同的访问路径可能会导致僵局 。 假锁争可能是由于哈希冲突 。 有只是一个在这个发言权无数的变量。 我甚至没有提到更高的隔离级别(可重复读,序列化)。

也许你应该使用快照隔离,不用担心这个问题?



文章来源: SQL Server - does [SELECT] lock [UPDATE]?