【问题标题】:What makes SQL Server decide what lock level to use (row, page or table lock?)是什么让 SQL Server 决定使用什么锁级别(行锁、页锁还是表锁?)
【发布时间】:2016-02-29 14:24:22
【问题描述】:

SQL Server 有很多locking resource 的方式。我试图了解是什么让 SQL Server 选择它将选择什么级别的锁。我想知道它什么时候会使用页锁或表锁而不是行锁?

问题

我有一个 PHP 应用程序,它对每个 http 请求使用事务,以确保在提交之前执行所有查询。令我困惑的一个问题是,当许多 (5+) 人使用该应用程序时,该应用程序似乎处于挂起状态(长时间旋转)!除了数据库锁,我能想到的任何事情都不会导致这种行为!我认为它发生的情况是 SQL Server 出于某种原因选择选择页锁或表锁而不是行锁。我试图确保 SQL Server 正在执行行锁而不是页锁或表锁。我正在使用 ORM,因此无法在查询中使用 ROWLOCK 提示。

有没有办法让我运行查询解释计划以查看将使用什么锁定级别?

【问题讨论】:

  • 您可以运行 SQL Profiler 来查看 SQL Server 创建的锁。我相信有一个 Lock:Escalation 事件类对您有用。您还可以查看许多其他锁定事件。
  • 要将其固定到数据库,您应该在行为出现时对数据库使用 SQL Server Profiler。您似乎已经得出结论,尽管它是 SQL Server,但这可能不正确。在询问为什么之前,首先要找到导致延迟的原因,这一点很重要。我建议还启用您的网络服务器上的日志记录并在那里分析日志。
  • @Witchfinder 我同意你的观点 100% 我不相信 SQL Server 锁是导致问题的原因,但在我看来,这是自那以后最重要的事情。您有检测实际问题的好方法吗?首先,我认为这是一个环境问题“我的网络服务器问题”我试图改变环境但还是一样。我不认为代码会导致这样的问题,因为没有我可以指出导致问题的无限循环(即使存在无限循环,我应该能够在单独运行应用程序时发现它)
  • 也许从监控磁盘队列、内存使用和 CPU 活动开始。也可以使用 SQL Server Profiler - 这至少可以让您停止运行 SQL Server,或者让您专注于数据库中正在发生的事情。该网站是对所有用户停止运行,还是仅对其他用户停止运行?
  • @Witchfinder 它似乎对每个人都停止了。我将听取您的建议并进行另一次测试,同时进行更好的监控,看看我是否能指出问题

标签: php sql-server locking


【解决方案1】:

如您所见,here 在锁定模式中没有默认粒度。

一般来说,优化器会选择最佳的行动方案来处理这个问题。

会不会是由于长时间运行的事务导致资源匮乏而导致的活锁?

您还可以查看herehere 以获取有关锁升级的信息,但我建议不要对任何表禁用它。

【讨论】:

  • 感谢您提供的信息。我刚刚快速阅读了有关活锁的内容。这什么时候会发生?可能值得一提的另一件事是,当我自己运行应用程序时,我没有遇到任何问题,并且一切运行顺利且非常快。每个事务可能有 50 多个查询,因为应用程序是数据驱动的系统,所以我预计会有大量的短查询。最长的查询在 15 毫秒内运行。大多数查询看起来像这样SELECT * FROM table when pk = '100' 或 SELECT * FROM table when pk = IN('100','101','102','103')`
  • 考虑以下情况:一个用户启动事务并通过更新一行来锁定 TableA,然后用户两个尝试更新 TableA 上相同的锁定行,第三个等等。然后该过程变为序列化。如果您有许多并发不间断请求,那么可能是其中一个用户永远不会(直到他超时)获得所需的资源。 Selects 不会锁定表以读取其他表,但会在它们运行任何更新/插入时锁定。
  • 谢谢你的例子。对于这个应用程序,我会说这是一个不可能的情况(每个请求都与一个会话(另一个表)相关联,会话 ID 与每个表相关联,每个用户将只能更新与他/她的会话 ID 关联的记录。但是,无论会话如何,我都有很多表将被所有人读取(只读)。
  • 我猜这些都是查找表。这应该不会影响他们。
猜你喜欢
  • 2012-04-04
  • 2013-09-23
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多