`
雪国列车
  • 浏览: 76946 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

在sqlserver中with(nolock)详解

 
阅读更多
在查询语句中使用 NOLOCK 和 READPAST
      处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAST 。有关 NOLOCK 和 READPAST的一些技术知识点:
      对于非银行等严格要求事务的行业,搜索记录中出现或者不出现某条记录,都是在可容忍范围内,所以碰到死锁,应该首先考虑,我们业务逻辑是否能容忍出现或者不出现某些记录,而不是寻求对双方都加锁条件下如何解锁的问题。
      NOLOCK 和 READPAST 都是处理查询、插入、删除等操作时候,如何应对锁住的数据记录。但是这时候一定要注意NOLOCK 和 READPAST的局限性,确认你的业务逻辑可以容忍这些记录的出现或者不出现:

简单来说:
NOLOCK 可能把没有提交事务的数据也显示出来.
READPAST 会把被锁住的行不显示出来
不使用 NOLOCK 和 READPAST ,在 Select 操作时候则有可能报错误:事务(进程 ID **)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。

下面就来演示这个情况。
为了演示两个事务死锁的情况,我们下面的测试都需要在SQL Server Management Studio中打开两个查询窗口。保证事务不被干扰。

演示一 没有提交的事务,NOLOCK 和 READPAST处理的策略:
查询窗口一请执行如下脚本:
CREATE TABLE t1 (c1 int IDENTITY(1,1), c2 int)
go
BEGIN TRANSACTION
insert t1(c2) values(1)

在查询窗口一执行后,查询窗口二执行如下脚本:
select count(*) from t1 WITH(NOLOCK)
select count(*) from t1 WITH(READPAST)

结果与分析:
查询窗口二依次显示统计结果为: 1、0
查询窗口一的命令没有提交事务,所以 READPAST 不会计算没有提交事务的这一条记录,这一条被锁住了,READPAST 看不到;而NOLOCK则可以看到被锁住的这一条记录。

如果这时候我们在查询窗口二中执行:
select count(*) from t1 就会看到这个执行很久不能执行完毕,因为这个查询遇到了一个死锁。

清除掉这个测试环境,需要在查询窗口一中再执行如下语句:
ROLLBACK TRANSACTION
drop table t1

演示二:对被锁住的记录,NOLOCK 和 READPAST处理的策略

这个演示同样需要两个查询窗口。
请在查询窗口一中执行如下语句:
CREATE TABLE t2 (UserID int , NickName nvarchar(50))
go
insert t2(UserID,NickName) values(1,'郭红俊')
insert t2(UserID,NickName) values(2,'蝈蝈俊')
go
BEGIN TRANSACTION
update t2 set NickName = '蝈蝈俊.net' where UserID = 2

请在查询窗口二中执行如下脚本:
select * from t2 WITH(NOLOCK) where UserID = 2
select * from t2 WITH(READPAST) where UserID = 2

结果与分析:
查询窗口二中, NOLOCK 对应的查询结果中我们看到了修改后的记录,READPAST对应的查询结果中我们没有看到任何一条记录。这种情况下就可能发生脏读
分享到:
评论

相关推荐

    SQL server 中锁机制详解

    "SQL Server 锁机制详解" SQL Server 中的锁机制是为了提供并发控制,防止多个事务同时访问同一个资源时出现的问题。锁机制可以分为悲观锁和乐观锁两种。 悲观锁是一种保守的锁机制,为任何操作(即使是 select)...

    SQL Server SQL优化

    在SQL Server的实际运行过程中,随着数据量的增长和用户访问频率的提升,数据库性能问题逐渐显现。根据所谓的“二八法则”,即大约20%的慢查询消耗了系统80%的资源,这表明对SQL查询进行优化具有极其重要的意义。...

    sql server 死锁检测

    ### SQL Server 死锁检测详解 #### 死锁的基本概念 死锁是计算机科学领域一个重要的概念,尤其在数据库管理系统中极为关键。死锁的本质是一种僵持状态,它发生在两个或多个事务相互等待对方释放资源时,从而导致...

    数据库sqlserver攻关

    在SQL Server中,可以使用BULK INSERT语句将查询结果导出到文本文件中,或者使用SQL Server Integration Services (SSIS)来实现数据的导入导出。 ### SQL数据更新原理 SQL Server中的数据更新原理涉及事务日志记录...

    sqlserver2008锁表语句详解(锁定数据库一个表)

    使用`SELECT * FROM table WITH (NOLOCK)`,SQL Server在执行查询时不会施加任何锁,允许读取未提交的数据(脏读),这等同于设置事务隔离级别为`READ UNCOMMITTED`,可能会导致不一致的数据读取。 4. **UPDLOCK**...

    经典SQLserver语句大全

    ### 经典SQL Server语句详解 #### 一、数据库管理 **1. 创建数据库** ```sql CREATE DATABASE database-name; ``` 此命令用于创建一个新的数据库。`database-name`应替换为希望创建的新数据库的名称。 **2. 删除...

    C#的Sql server学习笔记

    ### C#连接与操作SQL Server数据库及锁机制详解 #### 一、多程序并发更新同一行的不同字段 在多线程或多程序环境下,确保数据的一致性和完整性是非常重要的。当多个程序试图同时更新数据库表中同一行的不同字段时...

    Sql Server 开窗函数Over()的使用实例详解

    Sql Server的开窗函数Over()是数据库查询中的一个重要工具,它允许我们在不使用Group By的情况下对数据进行分组处理,并可以结合聚合函数进行复杂的计算。本文将深入探讨Over()函数的使用实例及其在排名和聚合方面的...

    详解SQL死锁检测的方法

    在SQL Server中,死锁是数据库管理系统中一个常见的问题,它发生在两个或多个并发事务之间,每个事务都在等待对方释放资源,导致它们无法继续执行。本文将深入探讨如何检测SQL Server中的死锁,并通过示例演示如何...

    【微软SQL2008精编】

    `SELECT * FROM table WITH (HOLDLOCK)` 是SQL Server 2008中的一个非常重要的特性,该命令用来对数据行进行锁定,直到事务结束才会释放锁。这种类型的锁称为持有锁(HOLDLOCK)。使用HOLDLOCK时,如果在事务中读取...

    详解Sql基础语法

    在SQL Server中,`sp_addumpdevice`存储过程用于定义备份设备,`BACKUP DATABASE`则用于执行备份。例如: ```sql USE master; EXEC sp_addumpdevice 'disk', 'NewBackup', 'C:\Backup\MyDatabase.bak'; BACKUP ...

    SQLservices锁表查询

    ### SQLservices锁表查询知识点详解 #### 一、SQL服务中的锁机制理解 在数据库管理系统中,锁(Lock)是一种非常重要的并发控制机制,用于确保数据的一致性和完整性。SQL Server 使用锁来管理多个用户对同一资源...

    全文搜索存储过程

    在存储过程的实现中,提到了`SQLFull-textFilterDaemonLauncher`,这实际上是SQL Server全文索引服务的一部分,负责启动全文搜索服务。确保此服务正在运行是全文搜索功能正常运作的前提。 #### 数据类型与目录配置 ...

Global site tag (gtag.js) - Google Analytics