Read Committed Isolation Level如何防止脏读

时间:2012-03-15 12:28:36

标签: sql-server dirtyread read-committed

我从一个简单的问题开始:

根据Dirty Read定义 WikipediaMsdn

我们有2个并发事务,T1和T2

当T1正在更新行而T2正在读取T1“尚未提交”的行时,会发生脏读:

但是在Read Committed Level读取数据后立即释放共享锁(不是在事务结束时甚至在语句结束时

那么Read Committed如何防止脏读?  Bkaz一旦在更新的行T2上发布共享锁可以读取更新的行并且t1可以回滚整个操作,那么我们在t1的手上有一个脏读

2 个答案:

答案 0 :(得分:1)

它可以防止脏读,因为T1对该行有一个锁定,因此T2无法读取可能在以后回滚的“尚未提交”的行。

Read Committed尝试解决的问题是:

T1创建一个事务并写一些东西

T2读取了什么

T1回滚交易

现在T2有一个实际上并不存在的数据。

根据数据库的结构,有两种“好”的可能性:

T1创建一个事务并写一些东西

T2等待T1结束交易

T2读取数据库在T1开始事务之前是如何进行的“快照”(使用行版本控制称为Read committed)

(MSSQL上的默认选项是第一个选项)

这里举例说明各种隔离级别的比较:http://msdn.microsoft.com/en-us/library/ms345124(SQL.90).aspx(在SQL Server 2005中提供的隔离级别下读取)

答案 1 :(得分:0)

当SQL Server在读提交的隔离级别执行语句时,它会逐行获取短期共享锁。这些共享锁的持续时间足够长,可以读取和处理每一行;服务器通常会在继续下一行之前释放每个锁。因此,如果在read committed下运行一个简单的select语句并检查锁(例如,使用sys.dm_tran_locks),通常一次最多只能看到一行锁。这些锁的唯一目的是确保语句只读取和返回已提交的数据。锁是有效的,因为更新总是获得一个独占锁,阻止任何试图获取共享锁的读者

摘自here