Faj*_*iya 7 sql-server locking update blocking
我正在学习 SQL Server 并试图了解 SQL Server 如何更新行。
据我了解,SQL Server首先对数据库加一个意向排它锁,然后对表加一个意向排它锁,然后对要更新的记录加一个更新锁。稍后,它将将该行上的更新锁转换为排他锁,以便可以修改该行中的数据。
但问题是共享锁与更新锁兼容。因此,虽然该行有更新锁,但其他会话仍然可以使用共享锁读取该行。如果行上有共享锁,则无法将更新锁转换为排它锁,因为共享锁和排它锁不兼容。
这是否意味着如果有会话连续读取该行,SQL Server 根本没有机会更新该行。这种情况可能会持续很长一段时间。这是真的?SQL Server 会等到该行上没有共享锁时才开始更新其中的数据吗?
我所说的“连续”是指一个会话读取该行,并且在从该行释放共享锁之前,另一个会话在同一行上放置一个共享锁。在第二个共享锁从该行释放之前,另一个会话在同一行上放置另一个共享锁,依此类推。因此,基本上,该行上总是至少有一个共享锁。
Pau*_*ite 10
在您描述的情况下,SQL Server 不会对数据库采用意向排他 (IX) 锁。IX 锁是在对象(表)级别以及包含目标行的页上获取的,然后再对行获取更新 (U) 锁。
\n新到达的重复共享 (S) 锁会阻止从更新 (U) 锁到排他 (X) 锁的转换的情况称为“锁饥饿”。SQL Server 采取措施来避免这种情况。
\n在 SQL Server 的早期版本中,锁是按照严格的先进先出 (FIFO) 顺序授予的。这意味着等待锁总是朝着队列的前面前进。
\n此后,这一安排已多次完善,但并未公开所有细节。如果您有兴趣,可以在Microsoft CSS 团队的SQL Server、Lock Manager 和 \xe2\x80\x9crelaxed\xe2\x80\x9d FIFO\xe2\x80\xa6中找到一些详细信息。简短的引用:
\n\n\n锁以宽松的先进先出 (FIFO) 方式授予。尽管顺序不是严格的 FIFO,但它保留了所需的属性,例如避免饥饿,并致力于减少不必要的死锁和阻塞。如果请求的模式与已授予的请求和待处理请求的模式的并集不兼容,则请求者尚未拥有资源锁的新锁请求将被阻止。仅当所请求的模式与所有授予的模式(不包括转换请求本身最初被授予的模式)的并集不兼容时,转换请求才会被阻止。
\n