-1

在具有默认配置的 SQL Server 2005 中,read_committed 隔离级别和 read_committed 快照关闭。查询会因为死锁而中止吗?如果是这样,为什么?

如果我将隔离级别提高到可重复读取会怎样?

根据 msdn 文件,任何级别的隔离都可能出现这种情况:

Transaction T_1 acquires a share lock on row 1.
Transaction T_2 acquires a share lock on row 2.
Transaction T_1 now requests an exclusive lock on row 2 ( because it wants to change it), and is blocked until transaction T_2 finishes and releases the share lock it has on row 2.
Transaction T_2 now requests an exclusive lock on row 1 ( because it wants to change it), and is blocked until transaction T_1 finishes and releases the share lock it has on row 1.
4

2 回答 2

1

SQL Server 使用几种类型的锁——如果它需要写入数据(例如插入新数据或更新现有行),它将需要使用排他锁——总是在任何隔离级别

由于您有独占锁在起作用,因此总是有可能发生死锁 - 进程 A 持有资源 A 的独占锁并需要对资源 B 的独占访问,而另一个进程 B 拥有资源 B 的独占锁并想要访问到资源 A。

这可能发生在任何隔离级别(即使使用READ UNCOMMITTED,SQL Server 将取出排他锁来写入数据!)我的观点是:隔离级别越严格,这些锁往往会停留的时间越长,因此机会就越高变成可能发生死锁。

如果您还没有 - 您应该阅读、重新阅读和重新阅读以下文章,直到您充分了解 SQL Server 锁定机制:

于 2012-11-11T19:44:12.863 回答
0

我建议您阅读文档以大致了解锁。

唯一不获取锁的语句类型是未提交读(脏)。
出于这个原因,我经常使用 read uncommitted 。

已提交的读取不使用排他锁,但它确实阻止了排他锁。
会不会导致死锁?
理论上它不会,因为更新总是可以等待读取提交的锁被清除。
在现实生活中,如果查询非常慢,等待排他锁可能会超时,但从技术上讲可能不是死锁。

所以查询可能会因为死锁而中止,但我认为查询不会直接导致死锁。

如果您有可能死锁的更新,那么大量读锁的存在会增加更新死锁的机会。考虑一个非常活跃的表。当更新 A 等待页面上的 readlock 清除时,更新 B 在同一页面上发挥作用。更新 A 和更新 B 死锁。如果更新 A 没有等待读取锁被清除,它就会进出。

于 2012-11-11T20:24:14.120 回答