2014-03-27 55 views
0

首先抱歉,如果我的英文不好。tsql事务级别明智锁定

我现在面临一个问题,相对于事务隔离级别。我目前的隔离级别是读取提交的,但它会导致表锁定有时。 例如

create table tmp(id int,name varchar(20)) 
insert into tmp(id,name) 
values(1,'Binesh') 
     ,(2,'Bijesh') 
     ,(3,'Bibesh') 
begin transaction 
update tmp set name ='Harish' where id=2 

我试图在另一个查询窗口

select * from tmp where id=1 

它锁定表,以便它不给予任何记录,直到我回滚获取或提交的第一个

我试图

ALTER DATABASE db 
SET READ_COMMITTED_SNAPSHOT On 
ALTER DATABASE db 
SET ALLOW_SNAPSHOT_ISOLATION on 

它不锁定表,但它给老id的值= 2

select * from tmp where id=2 

返回我Bijesh,我很期待锁定

我期待的方式一样,如果ID = 1它会正常工作,但如果ID = 2它将等待直到其他交易结束。

公司希望你的帮助.....提前

感谢

Binesh南比亚尔Ç

+0

SQL Server是**不**锁定表 - 它被锁定的行(带ID值从1到3)你是刚插入。那些不能被读取 - 直到INSERT被提交。 –

+0

使用WITH NOLOCK它将解决您的问题 – mohan111

+0

感谢您的重播,并且非常感谢您为我编写问题。我还认为marc告诉我们迄今为止(最近10年)。但是目前有些项目开始执行计划任务中的死锁。这导致了这个实验。在我的示例中插入不在任何事务中。如果你有疑问尝试一次在查询窗口中... –

回答

0

这不是您遇到了僵局。

你的第二个查询被阻止,因为它必须扫描整个表。在扫描过程中,它遇到正在更新(独占锁定)的行,所以它一直等到锁被释放(即事务结束)。

如果引擎知道这个ID列是唯一的(主键或唯一约束),你不会得到在这里堵,因为它不会对整个表做扫描,但宁愿停在第一场比赛。

保持ypur交易总之,数据(索引)提供替代的访问路径,并尽量不要使用“SELECT *”。

而且,仔细想想你是否真的想使用读取未提交的隔离级别。