SQL Server是否优先选择和更新语句?

时间:2015-07-22 18:53:21

标签: sql-server sql-server-2014

假设SQL服务器从不同的线程和连接同时收到同一个表的select和update语句

他们中的任何一个都被优先考虑吗?

我知道如果表已被锁定以进行更新,那么select语句会延迟到更新完成(默认情况下更新语句锁表我不正确吗?)。如果由于更新而导致表锁持续很长时间,则select语句会因为等待错误而被取消

那么当两者同时收到时会发生什么?

1 个答案:

答案 0 :(得分:2)

SELECT语句会在其正在读取的任何行上放置共享锁(S) - 具体取决于隔离级别,该锁将保留不同的时间。在默认的READ COMMITTED隔离级别中,只有在实际读取行时才会保持锁定 - 一旦读取,锁定就会立即释放。

共享锁与其他共享锁兼容 - 因此任意数量的SELECT语句都可以同时读取相同的行。

UPDATE语句会在要更新的行上放置更新(U)锁,以读取现有值。然后,在完成此操作之后,在写回实际更新值之前,锁定将在写入数据时转换为独占(X)锁定。这些锁保持,直到它们在中执行的事务被提交(或回滚)。

更新锁与另一个更新锁不兼容,也不与独占锁兼容。但它与共享锁兼容 - 因此,如果UPDATE语句当前仅读取现有值,则另一个事务可能使用SELECT语句读取相同的值共享锁。

exlusive锁与任何东西都不兼容 - 你甚至无法读取该行,而X锁定就在其上。

因此,如果您有两个语句并尝试访问同一行,那么:

  • 如果SELECT首先出现,它会在行上放置一个S锁定,读取它,并且通常会再次释放该锁定
  • 同时,UPDATE语句可以在行上放置U锁并读取现有值;在X锁定被释放之前,锁定到S的“促销”是不可能的 - 如果没有发生,UPDATE语句将等待,并最终超时,如果永远不会释放S

  • 如果首先出现UPDATE锁定,则会在该行上放置U锁定以读取现有值

  • 同时,另一个事务可能是在行上放置S锁来读取它
  • 并再次:UPDATE语句只能在X锁定消失后才能进入S级别以回写新值 - 否则会超时< / p>

  • 如果首先出现UPDATE锁定,它会在行上放置U锁定以读取现有值,并且已将X锁定放在行上实际上做了更新

  • 然后在这个时候,没有其他交易甚至可以读取该行 - 他们将不得不等待(或者超时,如果它们需要很长时间才能获得服务)

阅读SQL Server Transaction Locking and Row Versioning Guide以获得更深入的主题概述和更多详细信息