介绍
NOLOCK从字面意思可以看出就是没有锁,表示这段sql不去考虑目前table的transaction lock,就是说加上NOLOCK后不受锁的限制读取数据,包括已修改未提交的数据,概念上类似于读未提交READ UNCOMMITED隔离级别,
针对于SELECT语句。
优点:
-
- 提升查询性能
缺点:
-
- 脏读
示例:
首先创建一个测试表,如下:
前面说了NOLOCK会读取未提交数据,那就创造未提交的情况进行测试,
先插入一条记录,数据插入后未提交或者未回滚
BEGIN TRAN INSERT INTO dbo.TestA ( Name, Phone ) VALUES ( 'cc', -- Name - varchar(50) '3333' -- Phone - varchar(50) ) --COMMIT
--ROLLBACK
此时如果使用不加NOLOCK的语句查询,会出现阻塞;反之会发现,还没有完成事务的数据被读取出来了!
SELECT * FROM dbo.TestA SELECT * FROM dbo.TestA WITH(NOLOCK)
插入图示
查询图示
单独执行完ROLLBACK后会发现,读取不到了,或者执行COMMIT后加不加NOLOCK都能读取数据;
同理,UPDATE操作时,如果开始了一个事务,当此事务未执行完成,有个查询语句来查询该记录,能不能查询到该记录呢?答案显而易见,能!
首先执行如下修改语句
BEGIN TRAN UPDATE testA SET Phone='22222' WHERE id=1 --COMMIT --ROLLBACK
正常情况未加NOLOCK由于修改事务未完成,查询会阻塞,加上NOLOCK后,查询语句忽略修改操作的锁,直接读取所有数据。
读取到了!到这已经很清晰了,再执行一次COMMIT或者ROLLBACK,本次事务才算完成;
然而,加上NOLOCK的查询语句会导致读取到未提交的事务;
结语:
使用NOLOCK要想清楚是否会影响到数据读取,如果不考虑脏读,那么可以放心使用,还能提升查询的性能;
对于要事务完整性的数据就要好好考虑了。