2013-10-25 74 views
5

我对死锁的理解是 - 两个进程试图争夺相同的资源 - 通常是两个进程试图“写入”同一行数据。如果一个进程正在执行的是读取数据 - 而另一个进程正在更新数据,那么资源争用​​又如何?然而,在我们设置为默认事务级别“ReadCommitted”的数据库中,我们发现了几个死锁异常。 ReadComited definitin - 已被修改(但尚未提交)的数据无法读取。这很好 - 但是如果SQL Server遇到这种“脏读”发生时会抛出死锁异常? 任何人都有这种情况下的真实世界的经验?我发现了一篇博客帖子(由stackoverflow开发人员,不低于:)声称这可能是真实的。readcommitted隔离级别是否会导致死锁(Sql Server)?

谢谢

回答

2

是的,它可能发生。想象一下你有两个进程,每个进程都有自己的事务。第一次更新TableA然后尝试更新TableB。第二次更新TableB然后尝试更新TableA。如果你不走运,这两个进程都会完成第一步,然后无限期地等待另一个进程来完成第二步。顺便说一下,这是避免死锁的最常见方法之一:要更新表的顺序保持一致。如果两个进程都先更新TableA然后TableB,则不会发生死锁。

+0

那么你正在描述两个更新事务。在这种情况下,陷入僵局是有道理的。我的问题是 - 其中一个交易只是一个READ - 没有更新。另一个正在写入正在读取的相同记录。这怎么可能导致死锁? – user2736158

+0

除了我的头顶之外,这不应该陷​​入僵局,但如果您通过更多关于交易正在进行的细节的详细信息来编辑问题,我们可能会发现它的底部。 – acfrancis

2

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

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

2)正在编写/更新的用户2首先获取包含数据的数据库页面上的绝对锁定,然后尝试获取索引的独占锁定以更新索引。

+0

你也在谈论user1和user2都试图更新相同的记录。这种情况下的死锁是可以接受的。但是,我想知道是否有人从两个事务中看到了死锁结果 - 其中一个是写,另一个是读(当然是相同的数据)。 – user2736158

+0

看看我已经更新了答案并解释了。 –