如图上 显示 ,我们在使用SQL不可避免的会遇到锁的情况。如果单纯的全部是查询语句,我们不会等待事务的结束,然直接进行下一事务的查询。但是在实际业务中,我们不可能只是用到查询select语句。当独占锁即排它锁堵塞时,按理说我们所有的事务(查询,新增,修改,删除)对此表的操作都应该等待独占锁释放之后进行。这时候SQL的脏读的优势就提现出来了:在查询语句中加入with(Nolock)可以不必等待独占锁进行释放,可以直接进行查询。
代码片段1:独占锁占用但不释放
begin tran
update A set Name='222' where ID=1
--commit tran
代码片段2:共享锁查询A表数据
select * from A
代码片段3:查询允许脏读
select * from A with(NoLock)
代码片段4:查询锁
select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName ,*
from sys.dm_tran_locks where resource_type='OBJECT'
- 执行代码片段1时,再执行代码片段4,我们会发现独占锁未释放
- 执行代码片段1+执行代码片段2时,再执行代码片段4,我们会发现 代码1 在堵塞,代码2在等待执行中
- 执行代码片段1+执行代码片段3时,再执行代码片段4,发现只有代码片段1在堵塞。代码片段4执行成功。
注:使用脏读并不是不产生锁,而是生成Sch-S(架构稳定性)锁以及DB类型的共享锁。
额外补充:脏读知识点