2012-07-04 29 views
14

我想了解SQL Server中的隔离/锁定。什么时候/什么锁持有/发布READ COMMITTED隔离级别

我有以下的READ方案提交的隔离级别(默认)

我们有一个表。

create table Transactions(Tid int,amt int) 

with some records 

insert into Transactions values(1, 100) 
insert into Transactions values(2, -50) 
insert into Transactions values(3, 100) 
insert into Transactions values(4, -100) 
insert into Transactions values(5, 200) 

现在从MSDN我理解

当选择触发共享锁采取所以没有其它事务都不能修改数据(避免脏读)..文档也有关行级会谈,页面级,表级锁。我认为以下scenarion的

Begin Transaction 

select * from Transactions 

/* 
some buisness logic which takes 5 minutes 

*/ 

Commit 

我想了解的是什么时长的共享锁将被收购和(行,页表)。

只有在声明select * from Transactions正在运行时,才会获取锁定,否则将在整个5分钟内获取,直至达到COMMIT。

回答

6

锁将只能获得当select * from Transaction运行

你可以用下面的代码

检查打开一个SQL会话并运行此查询

Begin Transaction 

select * from Transactions 

WAITFOR DELAY '00:05' 
/* 
some buisness logic which takes 5 minutes 

*/ 

Commit 

打开另一个SQL会议及以下查询运行

Begin Transaction 
Update Transactions 
Set = ... 
where .... 
commit 
19

您正在问错误的问题请关注执行的详细信息。你应该考虑并关心的是隔离级别的语义。肯德拉小有一个很好的海报解释他们:Free Poster! Guide to SQL Server Isolation Levels

你的问题应该被改写,如:

SELECT * FROM项目

问:我会看到哪些项目?
答:所有提交的项目

问:如果有未插入/删除/更新项目的未提交事务会发生什么情况?
答:您的SELECT将阻塞,直到所有未提交的项目被提交(或回滚)。

问:如果新项目被插入/删除/更新,而我运行上面的查询会发生什么?
答:结果未确定。您可能会看到一些修改,不会看到其他一些修改,并且可能会阻止其中一些修改。

READ COMMITTED在您的陈述完成后不作承诺,与交易的长度无关。如果再次运行该语句,则会再次具有与之前的状态完全相同的语义,并且之前看到的项目可能会更改,消失并可能出现新项目。显然这意味着可以在您选择后对进行更改。

更高的隔离级别提供了更强的保证:REPEATABLE READ保证您在第一次选择的项目可以被修改或删除,直到您提交。 SERIALIZABLE增加了保证在您提交之前没有新的项目可以出现在您的第二个选择中。

这是你需要理解的,不是实现机制的工作原理。在掌握了这些概念之后,您可能会询问实施细节。它们全部在Transaction Processing: Concepts and Techniques中描述。

+0

当您获取表锁而不是行锁时,实现细节非常重要。 – matao

+0

肯德拉的小链接已损坏 – TinyTheBrontosaurus

6

你的问题是一个很好的问题。了解获取何种类型的锁可以深入理解DBMS。在SQL Server中,在所有隔离级别(读取未提交,读取提交(默认),可重复读取,可序列化)下,执行写入操作的独占锁定。

无论隔离级别如何,事务结束时都会释放专用锁。

隔离级别之间的差异是指共享(读)锁获取/释放的方式。

在读取未提交隔离级别下,不会收集共享锁。在此隔离级别下,会发生称为“Dirty Reads”的并发问题(允许事务从已由另一个正在运行的事务修改的行读取数据,但尚未提交,因此可能会回滚)。

在读取提交隔离级别下,为相关记录获取共享锁。当前指令结束时,共享锁将被释放。这个隔离级别可以防止“脏读”,但由于记录可以被其他并发事务更新,因此“非重复读”(事务A检索行,事务B随后更新行,事务A稍后再次检索同一行。事务A检索同一行两次,但看到不同的数据)或“幻像读取”(在事务过程中,执行两个相同的查询,第二个查询返回的行集合与第一个查询不同)可能发生。

在可重复读取隔离级别下,获取交易持续时间的共享锁。可以防止“脏读”和“不可重复读”,但仍然可以发生“幻像读”。

在可序列化的隔离级别下,范围内的共享锁是在事务持续时间内获取的。没有发生上述并发问题,但性能大幅降低,存在发生死锁的风险。

相关问题