日期:2014-05-17  浏览次数:20491 次

关于在SQL语句中no lock的指定
SQL Server 2008 R2

select * from table1(no lock) t1,table2(no lock) t2,table3(no lock) t3
where t1.id=t2.id and t3.id=t2



select * from table1 t1,table2 t2,table3 t3
where t1.id=t2.id and t3.id=t2


这二者有区别吗?难道这样的select语句也有锁?


问题源于:最近接手别人的项目,看了他的存储过程,几乎所有的多表select查询都显式指定no lock,有必要吗?

------解决方案--------------------
LZ可以了解一下事务隔离等级.

SQL Server默认的事务隔离等级是read commited(读取认可)..
所以默认不加nolock是需要申请S锁的.

加nolock是以read uncommited(读取未认可)..
所以不需加锁.
------解决方案--------------------
nolock就可以理解成read uncommited.也就是不加锁,不会有死锁发生
------解决方案--------------------
WIHT(NOLOCK)阻止select申请锁,换句话说,就是允许脏读。
未提交读:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM dbo.HR_PERSONS WITH(NOLOCK)
隔离级别最低,允许SELETE读取数据而不需要请求(S)锁,,这样就不会被(X)锁阻塞也不会阻塞(X)锁。允许SELETE读取正在修改中的数据,被称为脏读(dirty read)。适用于数据修改量小,读取数据准确性要求不高的应用程序。
如果事务依赖于SELETE语句读出数据精确性,或者事务不能承受其他事务的并发修改,则不能使用,因为读取数据时没有加锁,索引可能分离,可能导致查询返回的数据中多处或者丢失行,会造成不可预知的情况。
未提交读的意义在于关注报告和业务职能系统,而不是联机事务处理(OLTP)。