我正在调查我网站上的烦人问题。我们会定期在网站上发放奖品,但要参加比赛,人们必须登录。所以网站有时很忙。我发现当很多人尝试登录和注册时,我会在 UpdateUser,CheckPassword和GetUser 功能上遇到大量关于死锁的错误,然后服务器变得太忙而其他请求开始超时。
当我查看存储过程时,我发现'UpdateUser'上使用了ROWLOCK。那些ROWLOCK会导致死锁吗?或者只选择会导致死锁?
我正在考虑将NOLOCK用于我的情况,但经过一些研究后,显然不建议使用......
答案 0 :(得分:0)
正如 barry 已经解释过的那样,这两个提示可以相互补充,但它们通常用于不同的上下文中,以解决不同的资源争用问题。
WITH(NOLOCK)告诉服务器使用READ UNCOMMITTED事务隔离级别,这意味着您将面临读取未提交(“脏”)行的风险,这些行可能随后回滚,因此从未存在过。它确实可以防止读取时出现典型的死锁,但代价是获取无效数据。
如果有可能 GetUser 或 CheckPassword 操作可以通过 UpdateUser 操作访问正在更新的用户的个人资料,那么WITH(NOLOCK) )不建议使用。
WITH(ROWLOCK)表提示可以与SELECT,INSERT,UPDATE和DELETE语句一起使用,以指示服务器仅对正在修改或添加的行应用Range-Lock,并避免将锁升级到页面或表级别。其余行未锁定,可以通过其他查询访问。
但是,如果SQL Server上的默认事务隔离级别为READ COMMITTED或更严格,并且未启用SNAPSHOT READS,则如果查找条件匹配,则活动INSERT,UPDATE或DELETE事务仍可能阻止SELECT查询或重叠。
当查询只影响一行或仅几行时使用提示,以防止锁定锁定不会被查询删除的行。这将让另一个查询同时读取不相关的行,而不必等待删除完成。
如果在将删除大量行的查询上使用它,可能会降低性能,因为数据库会尽量避免将锁升级到更大的范围,即使它更有效。
答案 1 :(得分:-3)
WITH(NOLOCK)与SELECT语句一起使用,当检索到微秒的数据的时间敏感性不是非常重要时,或者选择新添加的记录正确关闭。
UPDATE语句使用WITH(ROWLOCK)来保持行的锁定在行级别锁定,而不是将其升级为多行甚至是表锁。
您应该始终在select语句和更新语句中使用它们,并且您需要正确创建索引,缓存重复数据以免快速查询数据库以查找变化不大的数据,并查看您的登录信息确定它是否没有执行不必要的数据记录的逻辑,并检查SQL错误日志以查找可能会减慢对您网站的访问速度的错误。