sql server with(nolock)

首先我们应该明白with(nolock)是表提示的一种,其主要的作用就是允许脏读,提高并发数,其他事务设置的排它锁不会阻止当前事务读取锁定的数据,关于脏读的概念,我们已实例来说明

假设有一张表如下:

我们sql server manager studio 打开一个回话窗口并执行以下sql语句:

begin tran
update dbo.userinfo set about_me='very good' where id=1

可以看到我们的代码并没有commit或者rollback,其就相当于是在真实环境中的事务中

然后我们再打开一个会话窗口(记住是另一个会话窗口,否则没有效果)执行以下sql语句:

select * from dbo.[userinfo]

我们会看到一直在执行中,没有数据显示,这个表中只有一条数据,没有意外都是瞬间显示结果,我们先获取第二个打开的会话窗口的唯一的session_id(可以类比为.net中的session_id)

select @@spid

 

如果此时我们想查看userinfo表中的数据怎么办呢,我们再开一个会话窗口,此时就可以使用with(nolock)提示:

 select * from dbo.userinfo WITH(NOLOCK)

看到是还未commit的数据,那么如果此时将第一个会话窗口的事务回滚或者直接将其会话kill掉的话,数据库中的数据其实是回滚到之前的值,但是我们用with(nolock)显示的是修改过的值,这就是所谓的脏读,实现如下:

打开低4个会话窗口

kill 68;
select * from dbo.userinfo

 

nolock vs with(nolock)

 select * from dbo.userinfo nolock;

该语句中的nolock只是起到别名的作用,没有其他的作用

select * from dbo.userinfo(nolock);
select * from dbo.userinfo with(nolock);
  1. (nolock) 与with(nolock)功能基本一致,(nolock)只是with(nolock)的别名
  2. 在sql server 2008及其之后的版本推荐使用 with(nolock), 在使用链接服务器中的sql语句中(nolock)会报错,with(nolock)不会

 with(nolock)会不会对数据库产生锁呢?

首先打开一个会话窗口执行下面的sql语句:

begin tran
alter table dbo.userinfo add cardid nvarchar(50);

然后打开另一个会话窗口执行以下的sql语句:

select * from dbo.userinfo with(nolock)

发现其一直在执行中,说明也是被阻塞的,其产生了TAB类型的架构稳定性锁

 

posted @ 2018-07-31 23:31  shermanli  阅读(254)  评论(0)    收藏  举报