我正在学习Server,并试图了解Server如何更新行。
据我所知,Server首先在数据库上放置意图排他锁,然后在表上放置意图排他锁,然后在要更新的记录上设置更新锁。稍后,它将将行上的update锁转换为独占锁,以便可以修改行中的数据。
但问题是共享锁与更新锁兼容。因此,尽管该行上有更新锁,但其他会话仍然可以使用共享锁读取行。使用行上的共享锁,不可能将更新锁转换为独占锁,因为共享锁和独占锁是不兼容的。
这是否意味着如果有会话持续读取行,Server就没有机会更新该行。这可能会持续很长一段时间。这是真的吗?Server会等到该行上没有共享锁,然后开始更新其中的数据吗?
所谓“连续”,我指的是会话读取行,在从该行释放共享锁之前,另一个会话将共享锁放在同一行。在第二个共享锁从行中释放之前,另一个会话会将另一个共享锁放在同一行上,等等。因此,基本上,该行上总是至少有一个共享锁。
发布于 2022-09-22 14:29:21
在所描述的情况下,Server不对数据库进行意图独占(IX)锁定。IX锁在对象(表)级别进行,在包含目标行的页面上,在对该行执行update (U)锁之前。
新到达的重复共享(S)锁将阻止从update (U)锁到独占(X)的转换,这种情况称为“锁饥饿”。Server采取步骤避免这种情况。
在Server的早期版本中,锁以严格的先入先出(FIFO)顺序授予.这意味着等待锁总是朝着队列前面的方向前进。
自那时以来,这一安排经过多次改进,并非所有细节都是公开的。如果您感兴趣,您可以在服务器、锁管理器和“轻松”FIFO…“中找到一些由Microsoft提供的细节。简短的引述:
锁是以轻松的先进先出(FIFO)的方式授予的.虽然命令不是严格的FIFO,但它保留了所需的属性,如避免饥饿,并致力于减少不必要的死锁和阻塞。如果请求者尚未拥有资源上的锁,则新的锁请求将被阻塞,如果请求模式与已授予请求的合并和挂起请求的模式不兼容。只有当请求的模式与所有已授予模式的合并不兼容时,转换请求才会被阻塞,但不包括最初授予转换请求本身的模式。
https://dba.stackexchange.com/questions/317240
复制相似问题