由于更新锁定导致的死锁问题

时间:2010-05-11 20:56:08

标签: sql-server

我们正试图追查死锁问题。我有一个从Profiler生成的死锁图(xdl)。它将丢失的SQL语句显示为简单的Select语句,而不是Update,Delete或Insert语句。该图显示丢失的Select语句为请求资源**but also owning an Update lock on a resource**上的共享锁定。这令我感到困惑。为什么不属于Insert,Update或Delete的Select语句在资源上持有Update锁?

我应该补充说,它所拥有的更新锁定位于被丢失的Select语句选择的表上。

编辑:请不要建议使用NoLock。是的,这将解决问题,但引入了一个新问题 - 脏读问题。此查询正在访问生产服务器。我真正想知道的是为什么Select语句会发出更新锁。

3 个答案:

答案 0 :(得分:6)

您确定SELECT 拥有 U锁吗?

如您所知,U和X锁(以及可序列化的S锁)在事务期间保留,而不是语句。因此,从先前执行的语句中发出写入的事务完全有可能拥有U锁。为什么它会拥有U锁,而不是X锁(即它拥有一个未升级为X 的U锁)本身就是一个难题,但我可以想象这可能发生的几种方式 因此,如果它是多语句事务的一部分,那么完全有可能拥有一个SELECT语句来拥有X / U锁。一个带有U锁的独立SELECT,我认为这有点不寻常。

典型的SELECT与UPDATE死锁发生在索引访问顺序方案中,如Read/Write deadlock中所述。我相信你已经仔细阅读了死锁图,但如果不是太多问题,你可以分享它吗?

哦,顺便问一下,你考虑过读过提交的快照吗?

答案 1 :(得分:1)

select语句确实会创建共享锁。尝试使用nolock提示进行选择。它可以解决问题。

例如select * from table(nolock)

答案 2 :(得分:0)

也许使用UPDLOCK提示调用了select? 无论如何,你可以使用快照隔离并消除问题吗?