首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ADO.NET DeadLock

ADO.NET DeadLock
EN

Stack Overflow用户
提问于 2010-11-03 19:28:13
回答 3查看 1.4K关注 0票数 0

下面的(简化)代码出现了间歇性的死锁情况。

代码语言:javascript
复制
DataSet my_dataset = new DataSet()
SqlCommand sql_command = new SqlCommand();

sql_command.Connection = <valid connection>
sql_command.CommandType = CommandType.Text;
sql_command.CommandText = 'SELECT * FROM MyView ORDER BY 1'

SqlDataAdapter data_adapter = new SqlDataAdapter(sql_command);

sql_command.Connection.Open();

data_adapter.Fill(my_dataset);

sql_command.Connection.Close();

我得到的错误是:

事务(进程ID 269)与另一个进程在锁定资源上陷入僵局,并被选择为死锁受害者。重新运行事务。

据我所知,简单地通过ADO.Net .Fill()命令填充一个.Fill不应该在数据库上创建一个锁。并且,从错误消息中可以看出锁是由另一个进程拥有的。我正在查询的视图只有select语句,但它确实将几个表连接在一起。

  • 只运行select语句的视图会受到锁定记录的影响吗?
  • ADO.Net .Fill()锁定记录可以吗?
  • 假设我需要填充一个DataSet,有什么方法可以避免潜在的数据锁吗?

Server 2005 (9.0.4035)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-11-03 19:58:28

带有联接的select查询确实会导致死锁。处理此问题的一种方法是使用快照隔离在SqlTransaction中执行查询。

代码语言:javascript
复制
using(SqlTransaction sqlTran = connection.BeginTransaction(IsolationLevel.Snapshot))
{
    // Query goes here.
}

死锁可能会发生,因为在执行联接之前,它会一个接一个地锁定每个表。如果另一个查询在另一个查询需要锁定的表上有一个锁,反之亦然,则存在一个死锁。对于刚刚从表中读取的快照隔离查询,不要锁定它们。完整性是维护的,因为读取实际上是在事务开始时根据数据的快照完成的。

但是,这可能会对性能产生负面影响,因为生成快照的开销很大。根据应用程序的不同,最好不要使用快照隔离,而是,如果查询失败,请等待一会儿,然后再试一次。

还可以尝试找出死锁发生的原因,并更改数据库的结构和/或修改应用程序以防止死锁。这个文章有更多的信息。

票数 2
EN

Stack Overflow用户

发布于 2010-11-03 20:02:30

你可以试试这个:

  • 降低该查询的事务级别(例如,IsolationLevel.ReadUncommited)。
  • 在查询中使用NOLOCK提示。
票数 1
EN

Stack Overflow用户

发布于 2010-11-03 19:35:32

它可能是遥远的,而不是你的问题的解决方案,首先检查其他解决方案-但是,我们有一个类似的问题(一个选择锁定记录!)经过大量的努力,我们跟踪到了文件/SMB层。似乎在沉重的负荷下,从网络驱动器(SAN)读取文件被耽搁了,在实际的数据库文件上创建了等待读取锁。这表示为对所包含的记录的锁定。

但这是一种比赛条件,在没有驱动器负载的情况下是不能繁殖的。哦,而且它也是Server 2005。

您应该能够使用Server包含的工具来确定哪些事务是死锁的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4090862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档