我正在尝试理解SQL Server中的隔离/锁。
在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我明白了
当一个select被触发时,共享锁被采用,这样其他事务就不能修改数据(避免脏读)。文档还讨论了行级、页级、表级锁。我想过跟随场景
Begin Transaction
select * from Transactions
/*
some buisness logic which takes 5 minutes
*/
Commit我想了解的是,共享锁将在多长时间内获得,以及哪一行、页、表等。
只有在语句select * from Transactions运行时才会获得Will锁,或者在我们到达COMMIT之前将获取整个5+分钟。
发布于 2012-07-04 11:56:59
只有在运行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发布于 2012-07-04 14:23:45
你问错了问题,你关心的是实现细节。您应该考虑和关注的是隔离级别的语义。肯德拉·利特尔( Kendra )有一张很好的海报,上面写着:免费海报!Server隔离级别指南。
你的问题应该重新措辞如下:
从项目中选择*
问:我会看到哪些物品?
答:所有已承诺的物品
问:如果有未提交的事务已经插入/删除/更新项目,会发生什么情况?
答:您的选择将阻塞,直到所有未提交的项目被提交(或回滚)。
问:如果在我运行上面的查询时插入/删除/更新新项目会发生什么?
答:结果尚未确定。在某些修改提交之前,您可能会看到一些修改,不会看到其他修改,以及可能的块。
一旦你的陈述完成,READ提交就不会做出任何承诺,这与交易的长度无关。如果您再次运行该语句,您将再次具有与之前的状态完全相同的语义,并且您之前看到的项可能会更改、消失,并出现新的项。显然,这意味着可以在选择之后对项进行更改。
更高的隔离级别提供了更强的保证:可重复的读取保证,在提交之前,您第一次选择的任何项都不能被修改或删除。SERIALIZABLE添加了在提交之前第二个选择中不会出现任何新项的保证。
这就是您需要理解的,不是实现机制是如何工作的。在掌握了这些概念之后,您可以询问实现细节。它们都是在事务处理:概念和技术中描述的。
发布于 2016-05-31 11:03:53
你的问题很好。在SQL Server中,在所有隔离级别(读未提交、读提交(默认)、可重复读取、可序列化)下,为写操作获取独占锁。
事务结束时会释放独占锁,而不管隔离级别如何。
隔离级别之间的差异是指获取/释放共享(读)锁的方式。
在读取未提交的隔离级别下,不获取共享锁。在此隔离级别下,称为"Dirty“的并发问题(允许事务从已被另一个正在运行的事务修改但尚未提交的行读取数据,因此可以回滚)。
在Read提交隔离级别下,为相关记录获取共享锁。当当前指令结束时,共享锁被释放。此隔离级别防止“脏读”,但是,由于记录可以由其他并发事务更新,“不可重复读取”(事务A检索一行,事务B随后更新行,事务A随后再次检索同一行)。事务A检索同一行两次,但看到不同的数据)或“幻影读取”(在事务处理过程中,执行两个相同的查询,第二个查询返回的行集合与第一个查询不同)。
在可重复读取隔离级别下,在事务持续时间内获取共享锁。“脏读”和“不可重复读”是被阻止的,但是“幻影读”仍然可能发生。
在可序列化隔离级别下,在事务持续时间内获取远程共享锁。上面提到的并发问题都没有发生,但是性能急剧下降,出现死锁的风险也很大。
https://stackoverflow.com/questions/11328180
复制相似问题