Har*_*OTA 11 c# sql deadlock database-deadlocks
我尝试从C#中的SQL数据库获取数据时生成了这两个异常:
System.Data.SqlClient.SqlException:事务(进程ID 97)在锁资源上与另一个进程死锁,并被选为死锁牺牲品.
要么
System.Data.SqlClient.SqlException:事务(进程ID 62)在锁资源上与另一个进程死锁,并被选为死锁牺牲品.
要么
System.Data.SqlClient.SqlException:事务(进程ID 54)在锁资源上与另一个进程死锁,并被选为死锁牺牲品.重新运行该交易.
这是代码:
using (SqlConnection con = new SqlConnection(datasource))
{
SqlCommand cmd = new SqlCommand("Select * from MyTable Where ID='1' ", con);
cmd.CommandTimeout = 300;
con.Open();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds);
con.Close();
return ds.Tables[0];
}
Run Code Online (Sandbox Code Playgroud)
这些都发生在每一次.
关于如何解决这些问题的任何想法?
Dav*_*kle 21
您可以采取一些措施来减少您收到的死锁数量,并且可以采取一些措施来彻底消除死锁.
首先,启动SQL Server Profiler并告诉它为您提供死锁图.运行此跟踪将告诉您与您的查询冲突的其他查询.您的查询非常简单,但我严重怀疑您SELECT *在系统中有一个名为MyTable的表的查询...
无论如何,使用死锁图和其他查询,您应该能够告诉哪些资源是死锁.经典的解决方案是更改两个查询的顺序,以便以相同的顺序访问资源 - 这可以避免循环.
你可以做的其他事情:
SET TRANSACTION ISOLATION LEVEL SNAPSHOT在适当的时候在事务中使用.还可以使用行版本控制启用读取提交.在许多情况下,这足以完全消除大多数死锁.了解事务隔离级别. 了解你在做什么.并不是说这会有助于解决僵局问题,但是你应该处理你的其他IDisposable对象,就像你处理你的SqlConnection那样:
using (SqlConnection con = new SqlConnection(datasource))
using (SqlCommand cmd = new SqlCommand("Select * from MyTable Where ID='1' ", con))
{
cmd.CommandTimeout = 300;
con.Open();
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
using (DataSet ds = new DataSet())
{
adapter.Fill(ds);
return ds.Tables[0];
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过查询中的锁定提示来避免锁定:
Select * from MyTable with (nolock) Where ID='1'
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.