tsql事务级行锁定

tsql事务级行锁定,sql,sql-server,tsql,transactions,Sql,Sql Server,Tsql,Transactions,首先,如果我的英语不好,我很抱歉 我面临一个关于事务隔离级别的问题。我当前的隔离级别是read-committed,但有时会导致表死锁。 比如说 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' w

首先,如果我的英语不好,我很抱歉

我面临一个关于事务隔离级别的问题。我当前的隔离级别是read-committed,但有时会导致表死锁。 比如说

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 Nambiar C

这不是您正在经历的死锁

您的第二个查询被阻止,因为它必须扫描整个表。在扫描过程中,它遇到正在更新的行(以独占方式锁定),因此它会等待直到解除锁定(即事务结束)

如果引擎知道id列是唯一的(主键或唯一约束),您将不会在这里被阻塞,因为它不必扫描整个表,而是在第一次匹配时停止

保持ypur事务简短,提供数据(索引)的替代访问路径,并尝试不使用“选择*”


另外,请仔细考虑是否确实要使用“读取未提交”隔离级别。

SQL Server并没有锁定该表,而是锁定了刚插入的行(id值为1到3)。在
插入
提交之前,无法阅读这些内容。使用NOLOCK它将解决您的问题谢谢您的重播,非常感谢您为我解答了这个问题。正如marc所说,我也一直在思考(过去10年)。但目前一些项目开始陷入死锁,这些项目都在预定的任务中。这是这个实验的线索。在我的示例中,Insert不在任何事务下。若您有疑问,请在查询窗口中尝试一次……您好,莫汉,我不希望看到witn(nolock)。它作为隔离级别read uncommitted工作。我希望是行级别锁定。但是我可以获得表锁定或不锁定。您忘记了通过调用commit来结束事务