SQL Server 2005:中止查询会导致死锁

时间:2012-11-11 18:25:34

标签: sql-server tsql sql-server-2005

在具有默认配置的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.

2 个答案:

答案 0 :(得分:1)

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

由于您在游戏中拥有独占锁,因此始终存在死锁的可能性 - 进程A在资源A上拥有独占锁并且需要对资源B的独占访问,而另一个进程B在资源B上具有独占锁并希望访问资源A.

这可能发生在任何隔离级别(即使使用READ UNCOMMITTED,SQL Server将取出用于写入数据的独占锁!)我的观点是:隔离级别越严格,这些锁往往会越来越长,因此发生死锁的可能性就越大。

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

答案 1 :(得分:0)

我建议您阅读文档以获得对锁的一般理解。

未获取锁定的唯一类型的语句是未提交的(脏) 出于这个原因,我使用了很多未经提交的读取。

提交的读取不会采用独占锁定,但它会阻止独占锁定 它会导致僵局吗? 理论上它不会因为更新总是等待读取提交的锁定清除 在现实生活中如果查询非常慢,等待的独占锁可能会超时,但技术上可能不是死锁。

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

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