2010-05-11 83 views
2

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

我应该补充说它拥有的更新锁是在由Select Select语句选择的表上。

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

回答

6

您确定SELECT 拥有的U锁吗?

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

典型的SELECT与UPDATE死锁发生在索引访问顺序场景中,如Read/Write deadlock中所述。我相信你对死锁图进行了认真的阅读,但是如果没有太多要问,你能分享吗?

哦,顺便说一句,你有没有考虑读取承诺的快照?

+0

我很乐意分享它。我应该怎么做? – 2010-05-11 22:49:48

+0

如果您无法在线分享,请将其发送给我。我的电子邮件位于我的网站上的联系页面http://rusanu.com/contact-us – 2010-05-11 22:54:18

+0

我只是在联系页面上的电子邮件地址。 – 2010-05-12 00:00:58

1

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

eg select * from table(nolock)

+0

+1是(nolock)是这里的关键。 – 2010-05-11 21:03:00

+1

@Byron - 是的,我知道选择创建共享锁。我的问题涉及更新锁。 NoLock解决了一个问题并引入了另一个问题。它解决了锁定问题并引入了一个脏读取问题。 – 2010-05-11 21:32:10

0

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