readcommitted隔离级别是否会导致死锁(Sql Server)?

时间:2013-10-25 16:34:25

标签: sql sql-server deadlock

我对死锁的理解是 - 两个进程试图争用相同的资源 - 通常是两个进程试图'写'到同一行数据。如果所有进程都在读取数据 - 而另一个进程正在更新数据,那么资源争用​​情况如何?然而,在我们的数据库中,设置为默认事务级别“ReadCommitted”,我们看到了几个死锁异常。 ReadComitted definitin - 无法读取已修改(但尚未提交)的数据。这很好 - 但是如果遇到这种“脏读”,SQL Server会抛出死锁异常吗? 有没有人对这种情况有真实的经验?我发现了一篇博文(由stackoverflow开发人员发布,并没有减少:)声称这可能是真的。

由于

2 个答案:

答案 0 :(得分:3)

是的,它可能发生。想象一下,你有两个进程,每个进程都有自己的事务。第一次更新TableA然后尝试更新TableB。第二次更新TableB然后尝试更新TableA。如果你运气不好,两个进程都会设法完成第一步,然后无限期地等待另一个进程,以完成第二步。

顺便说一句,这是避免死锁的最常见方法之一:按照更新表的顺序保持一致。如果两个进程首先更新TableA然后更新TableB,则不会发生死锁。

答案 1 :(得分:3)

ReadComitted 事务隔离级别最初在资源上获得Shared Lock,即在读取行时,但是当我们尝试更新行时,它会在资源上获得Exclusive lock。多个用户可以在同一行上拥有共享锁,但是只要一个用户尝试更新一行,就会在该行上获得一个独占锁定,当一个用户最初可以看到该行时,会导致A dead lock记录,因为行上的共享锁,但现在当用户尝试更新它时,第一个用户已经有一个独占锁。想象一下,User1和User2都有共享锁的情况,当他们尝试更新某些记录时,他们都会获得其他用户需要提交事务的行的独占锁。这将导致死锁。
对于DeadLock,如果Priority Level is not set SQL Server将等待某个时间,然后它将RollBack要回滚的cheaper事务。
修改
是,如果User1只读取数据而User2尝试更新某些数据,并且该表上有非聚集索引,则可以。

1)User1正在读取Some Data并获取非聚集索引上的共享锁以执行查找,然后尝试在页面上获取共享锁,以便返回数据本身以返回数据。

2)正在编写/更新的User2首先在包含数据的数据库页面上获得一个exlusive锁,然后尝试获取索引的独占锁,以便更新索引。