1

我目前正在我的网站上调查一个烦人的问题。我们会定期在网站上发放奖品,但要参加比赛,人们必须登录。所以网站有时会变得很忙。我发现当很多人尝试登录和注册时,我会收到很多关于UpdateUser、CheckPassword 和 GetUser函数死锁的错误,然后服务器变得太忙,其他请求开始超时。

当我查看存储过程时,我发现“UpdateUser”上使用了 ROWLOCK。那些 ROWLOCK 会导致死锁吗?还是只有选择会导致死锁?

我正在考虑针对我的情况使用 NOLOCK,但经过一番研究,显然不建议这样做......

4

2 回答 2

0

正如barry已经解释的,这两个提示可以相互补充,但它们通常用于不同的上下文并解决不同的资源争用问题。

WITH (NOLOCK) 告诉服务器使用 READ UNCOMMITTED 事务隔离级别,这意味着您面临读取未提交(“脏”)行的风险,这些行可能随后被回滚,因此从未存在过。它确实可以防止经典的读取死锁,但会以获取无效数据为代价。

如果GetUserCheckPassword操作有可能通过UpdateUser操作访问正在更新的用户的配置文件,则不建议使用 WITH (NOLOCK)。

WITH (ROWLOCK) 表提示可以与 SELECT、INSERT、UPDATE 和 DELETE 语句一起使用,以指示服务器仅对正在修改或添加的行应用 Range-Lock(s),并避免升级锁到页或表级别。其余行未锁定,可以由另一个查询访问。

但是,如果 SQL Server 上的默认事务隔离级别是 READ COMMITTED 或更严格,并且未启用 SNAPSHOT READS,则如果查找条件匹配或重叠,则活动的 INSERT、UPDATE 或 DELETE 事务可能仍会阻止 SELECT 查询。

当查询仅影响单个或仅几行时使用提示,以防止锁定锁定不会被查询删除的行。这将使另一个查询同时读取不相关的行,而不必等待删除完成。

如果您在将删除大量行的查询上使用它,它可能会降低性能,因为数据库将尝试避免将锁升级到更大的范围,即使它会更有效。

于 2017-09-14T11:13:10.690 回答
-3

WITH (NOLOCK) 与 SELECT 语句一起使用,当检索数据的时间敏感性下降到微秒时不是 eccential,或者选择新添加的记录正确下降。

UPDATE 语句使用 WITH (ROWLOCK) 将行锁定保持在行级锁定,而不是将其升级为多于一行甚至是表锁定。

您应该始终在您的选择语句和更新语句中使用,以及您需要正确创建索引、缓存重复数据以避免快速查询数据库以获取变化不大的数据,并查看您的登录逻辑以确定如果它没有执行不必要的数据记录,并检查您的 SQL 错误日志以查找可能会减慢您网站访问速度的错误。

于 2012-10-04T16:09:15.713 回答