在查询语句中使用 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,'lucas') 
insert t2(UserID,NickName) values(2,'fuckcpp') 
go

BEGIN TRANSACTION 
update t2 set NickName = 'fuckcpp.net' where UserID = 2

请在查询窗口二中执行如下脚本:

select * from t2 WITH(NOLOCK) where UserID = 2 
select * from t2 WITH(READPAST) where UserID = 2

结果与分析:

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

SQLSERVER中WITH(NOLOCK)详解的更多相关文章

  1. 在sqlserver 中with(nolock)详解

      所有Select加 With (NoLock)解决阻塞死锁        在查询语句中使用 NOLOCK 和 READPAST  处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK  ...

  2. SqlServer中计算列详解

    计算列区别于需要我们手动或者程序给予赋值的列,它的值来源于该表中其它列的计算值.比如,一个表中包含有数量列Number与单价列Price,我们就可以创建计算列金额Amount来表示数量*单价的结果值, ...

  3. SqlHelper帮助类_上(SQLServer数据库含Connection详解)

    在操作数据库时,经常会用到自己封装的SqlHelper.这里主要对SQLServer数据库的Sqlhelper,主要用于在同一个连接中完成CRUD! 一.ADO.NET中的Connection详解: ...

  4. php中关于引用(&)详解

    php中关于引用(&)详解 php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的变量名访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的 ...

  5. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

  6. AngularJS select中ngOptions用法详解

    AngularJS select中ngOptions用法详解   一.用法 ngOption针对不同类型的数据源有不同的用法,主要体现在数组和对象上. 数组: label for value in a ...

  7. 【转载】C/C++中extern关键字详解

    1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...

  8. oracle中imp命令详解 .

    转自http://www.cnblogs.com/songdavid/articles/2435439.html oracle中imp命令详解 Oracle的导入实用程序(Import utility ...

  9. Android中Service(服务)详解

    http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...

随机推荐

  1. 【转】Doscommand-操作Cmd的第三方控件

    核心用法: Doscommand1.CommandLine := 'cmd /c' +[命令];Doscommand1.OutputLines :=Memo1.Lines;Doscommand1.Ex ...

  2. C# 判断是否为闰年的条件各是

    //try 没增加异常数据处理 Console.WriteLine("根据输入的信息计算当年某个月份的天数,以及当年是否是闰年或平年,\n并判断2月份特殊月份的天数."); Con ...

  3. [terry笔记]Oracle会话追踪(二):TKPROF

    接上一笔记[terry笔记]Oracle会话追踪(一):SQL_TRACE&EVENT 10046 http://www.cnblogs.com/kkterry/p/3279282.html ...

  4. openstack做镜像

    virt-install --virt-type kvm --name windows2008 --ram 1024 --cdrom /opt/windows-2008-x86_64.iso --di ...

  5. 【Cocoa】 Initializing View Instances Created in Interface Builder

    Initializing View Instances Created in Interface Builder View instances that are created in Interfac ...

  6. (转)Android网络命令

    转自:http://www.cnblogs.com/shunyao8210/archive/2010/08/10/1796214.html ifconfig 1.       作用 ifconfig用 ...

  7. DOS通讯录

    #include"stdio.h" #include"string.h" #include"stdlib.h" FILE *fp; #def ...

  8. 算法系列8《Base64》

    Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,Base64编码可用于在HTTP环境下传递较长的标识信息.在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单 ...

  9. Linux下如何查看JDK安装路径

    1:echo $JAVA_HOME 使用$JAVA_HOME的话能定位JDK的安装路径的前提是配置了环境变量$JAVA_HOME,否则如下所示,根本定位不到JDK的安装路径 [root@localho ...

  10. SequoiaDB版本升级及导入导出工具说明

    升级SequoiaDB数据库指导 SequoiaDB安装路径:SDB_HOME=/opt/sequoiadb 数据存储路径:DATABASE=/ opt/sequoiadb/database 一.导出 ...