重复读取和一次写入的 SQL Server 锁定行为

Tem*_*udi 3 sql-server locking

我很好奇:假设 SQL Server(或任何其他数据库管理系统)在一个表上接收大量读取流量,因此在任何时间点,至少请求(并且可能授予)一个读取锁。现在假设出现了一个写锁定请求。

写锁是否曾经发出过?还是只要没有授予写锁就总是授予读锁,这样就永远不会授予写锁?锁定请求是否按到达的顺序提供?还是通过更复杂的优先级方案在某个更难确定的时间点发出写锁?

Pau*_*ite 6

多年来,细节发生了一些变化,并且会不时进行调整。可以在Microsoft 的 Bob Ward 的SQL Server、Lock Manager 和“宽松”FIFO 中找到回答问题中广泛观点的合理总结。

锁定以宽松的先进先出 (FIFO) 方式授予。尽管顺序不是严格的 FIFO,但它保留了所需的特性,例如避免饥饿并减少不必要的死锁和阻塞。如果请求的模式与授权请求的联合和挂起请求的模式不兼容,则请求者尚未拥有资源锁的新锁请求将被阻止。仅当请求的模式与所有授予的模式的并集不兼容时,转换请求才会被阻止,不包括最初授予转换请求本身的模式。

与 SQL Server 2000 相比,SQL Server 2005 中的 FIFO 授予算法明显放宽。这种放宽影响了与所有保持模式和所有挂起模式兼容的请求。在这些情况下,可以通过传递任何未决请求立即授予新锁。因为它与所有挂起的请求兼容,所以新请求的模式不会导致饥饿。在 SQL Server 2000 中,不会批准新请求,因为在其更严格的 FIFO 实现下,只有在批准所有先前发出的请求后才能批准新请求。

相关阅读(全部由 Bob Dorr – 首席软件工程师 SQL Server):


严格的 FIFO 主要是针对 Sch-M/Sch-S 锁重新设置的。在 SQL Server 2012 中,Sch-M WAIT 会阻止 SQL Server 2014 中的 Sch-S,但不会阻止 SQL Server 2008 R2?, 以防止挂起的 Sch-M 锁被饿死,通过在 SQL Server 2014 中引入低优先级等待进一步修改。