下面的(简化)代码出现了间歇性的死锁情况。
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语句,但它确实将几个表连接在一起。
Server 2005 (9.0.4035)
发布于 2010-11-03 19:58:28
带有联接的select查询确实会导致死锁。处理此问题的一种方法是使用快照隔离在SqlTransaction中执行查询。
using(SqlTransaction sqlTran = connection.BeginTransaction(IsolationLevel.Snapshot))
{
// Query goes here.
}死锁可能会发生,因为在执行联接之前,它会一个接一个地锁定每个表。如果另一个查询在另一个查询需要锁定的表上有一个锁,反之亦然,则存在一个死锁。对于刚刚从表中读取的快照隔离查询,不要锁定它们。完整性是维护的,因为读取实际上是在事务开始时根据数据的快照完成的。
但是,这可能会对性能产生负面影响,因为生成快照的开销很大。根据应用程序的不同,最好不要使用快照隔离,而是,如果查询失败,请等待一会儿,然后再试一次。
还可以尝试找出死锁发生的原因,并更改数据库的结构和/或修改应用程序以防止死锁。这个文章有更多的信息。
发布于 2010-11-03 20:02:30
你可以试试这个:
IsolationLevel.ReadUncommited)。NOLOCK提示。发布于 2010-11-03 19:35:32
它可能是遥远的,而不是你的问题的解决方案,首先检查其他解决方案-但是,我们有一个类似的问题(一个选择锁定记录!)经过大量的努力,我们跟踪到了文件/SMB层。似乎在沉重的负荷下,从网络驱动器(SAN)读取文件被耽搁了,在实际的数据库文件上创建了等待读取锁。这表示为对所包含的记录的锁定。
但这是一种比赛条件,在没有驱动器负载的情况下是不能繁殖的。哦,而且它也是Server 2005。
您应该能够使用Server包含的工具来确定哪些事务是死锁的。
https://stackoverflow.com/questions/4090862
复制相似问题