假设SQL服务器从不同的线程和连接同时收到同一个表的select和update语句
他们中的任何一个都被优先考虑吗?
我知道如果表已被锁定以进行更新,那么select语句会延迟到更新完成(默认情况下更新语句锁表我不正确吗?)。如果由于更新而导致表锁持续很长时间,则select语句会因为等待错误而被取消
那么当两者同时收到时会发生什么?
答案 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以获得更深入的主题概述和更多详细信息