我有一个VB6应用程序通过ADO访问MSSQL2000服务器上的单个表。我使用的是只读访问(adOpenStatic,adLockReadOnly) --网络中还有其他的应用程序会对表进行更改。
由于某些原因,我的应用程序被选择为死锁受害者时会出现错误。
我真的很困惑:当我是时,为什么会有一个死锁,我只是从一个表中读取?我希望超时,因为其他应用程序的编写,但不是死锁.
有人能解释一下这件事吗?
更新: 2009-06-15我仍然对这个问题的解决方案感兴趣.所以我提供一些更多的信息:
发布于 2009-05-27 12:57:20
由于存在非聚集索引,单个SELECT语句可能会对单个UPDATE或DELETE语句死锁,请考虑以下情况:
读取器(您的应用程序)首先获得非聚集索引上的共享锁,以执行查找,然后尝试获取页上的共享锁,合并数据以返回数据本身。
作者(其他应用程序)首先在包含数据的数据库页上获得一个外部锁,然后尝试获取索引上的独占锁,以便更新索引。
您可以在Microsoft KB文章Q169960 (http://support.microsoft.com/kb/q169960/)中找到有关这种(和其他)类型死锁的更多信息。
另外,您可能想了解一下Google如何获得死锁跟踪信息(跟踪标志1222) --这将报告每当出现死锁时,哪些SQL语句与哪些对象发生冲突。这是一篇相当不错的文章- http://blogs.msdn.com/bartd/archive/2006/09/09/747119.aspx
发布于 2009-06-16 11:18:23
我认为在这里已经提供了一些可能的答案。由于您只使用共享锁,所以死锁不能是由于锁升级造成的,而必须只是获取与其他进程中获得的锁不兼容的锁,并以不同的顺序获取这些锁.
您的共享锁与另一个接受独占锁的进程不兼容。可能会发生这样的情况..。
注:死锁可以有更多的玩家,而不仅仅是2人。有时会有一条完整的相互交织的活动链导致死锁,但原则是一样的。
通常,如果多个应用程序访问同一个数据库,就会有一个通过存储过程管理所有访问的DBA,这样他就可以确保资源总是按照相同的顺序锁定。如果您不在这种情况下,而其他应用程序使用的是即席SQL语句,则必须检查它们的代码,以确定它们是否可能与我描述的应用程序发生冲突。听起来不好玩。
一种实用的解决方案可能是,当您的事务作为死锁受害者被杀死时,捕获错误,然后简单地多次重试该事务。根据其他应用程序产生的活动数量,您可能会以这种方式获得可接受的结果。
发布于 2009-06-15 15:17:24
https://stackoverflow.com/questions/847139
复制相似问题