SqlServer的with(nolock)关键字的用法介绍

举个例子

下面就来演示这个情况。

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

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

SqlServer的with(nolock)关键字的用法介绍_第1张图片

select count(*) from t1 WITH(NOLOCK)
select count(*) from t1 WITH(READPAST) 
--结果与分析:

SqlServer的with(nolock)关键字的用法介绍_第2张图片

查询窗口二依次显示统计结果为:1、0

查询窗口一的命令没有提交事务,所以 READPAST 不会计算没有提交事务的这一条记录,这一条被锁住了,READPAST 看不到;而NOLOCK则可以看到被锁住的这一条记录。 

select count(*) from t1 

如果这时候我们在查询窗口二中执行:

select count(*) from t1 就会看到这个执行很久不能执行完毕,因为这个查询遇到了一个死锁。

 SqlServer的with(nolock)关键字的用法介绍_第3张图片

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

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 

SqlServer的with(nolock)关键字的用法介绍_第4张图片

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

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

SqlServer的with(nolock)关键字的用法介绍_第5张图片

结果与分析:

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

三、with(nolock)的适用场景

1、数据量特别大的表,牺牲数据时效性来提升性能是可以考虑的;

2、允许出现脏读现象的业务逻辑,反之一些数据完整性要求比较严格的场景就不合适了,像电商、金融方面等。

3、数据不经常修改的表,这样会省掉锁定表的时间来加快查询速度。

4、当使用NoLock时,它允许阅读那些已经修改但是还没有交易完成的数据。因此如果有需要考虑transaction事务数据的实时完整性时,使用WITH (NOLOCK)就要好好考虑一下

SQL常用脚本整理(上)

SQL server数据库的导入导出

SQL语句简例

 SQL Server触发器的基本语法和使用方法

不备份等于自杀?!学会SQL Server数据库备份的正确姿势!

数据库SQL经典面试题详解_软件测试sql面试题_墨石测试攻略的博客-CSDN博客

你可能感兴趣的:(SqlServer,sqlserver,数据库,sql)