我在C#中创建简单的控制台应用程序来模拟死锁错误。我使用了两个线程。代码:
class Program
{
static void Main(string[] args)
{
Thread[] tt = new Thread[2];
try
{
tt[0] = new Thread(queryAdo1);
tt[0].Priority = ThreadPriority.Highest;
tt[0].Start();
tt[1] = new Thread(queryAdo2);
tt[1].Priority = ThreadPriority.Highest;
tt[1].Start();
}
catch (Exception ex)
{
Console.WriteLine(ex);
Console.ReadLine();
}
}
private static void queryAdo1()
{
try
{
SqlConnection con = new SqlConnection("data source=.; database=BazaTest; integrated security=SSPI");
SqlCommand cmd = new SqlCommand("spTransaction1", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Console.WriteLine("Done Well 1");
}
catch (SqlException ex)
{
if (ex.Number == 1205)
{
Console.WriteLine("DeadLock 1");
Console.ReadLine();
}
}
}
private static void queryAdo2()
{
try
{
SqlConnection con = new SqlConnection("data source=.; database=BazaTest; integrated security=SSPI");
SqlCommand cmd = new SqlCommand("spTransaction2", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Console.WriteLine("Done Well 2");
}
catch (SqlException ex)
{
if (ex.Number == 1205)
{
Console.WriteLine("DeadLock 2");
Console.ReadLine();
}
}
}
}
存储过程:
Create table TableA
(
Id int identity primary key,
Name nvarchar(50)
)
Go
Insert into TableA values ('Mark')
Go
Create table TableB
(
Id int identity primary key,
Name nvarchar(50)
)
Go
Insert into TableB values ('Mary')
Go
Create procedure spTransaction1
as
Begin
Begin Tran
Update TableA Set Name = 'Mark Transaction 1' where Id = 1
Waitfor delay '00:00:05'
Update TableB Set Name = 'Mary Transaction 1' where Id = 1
Commit Transaction
End
Create procedure spTransaction2
as
Begin
Begin Tran
Update TableB Set Name = 'Mark Transaction 2' where Id = 1
Waitfor delay '00:00:05'
Update TableA Set Name = 'Mary Transaction 2' where Id = 1
Commit Transaction
End
当我运行我的代码时,我在控制台中得到响应:
Done well 1
Deadlock 2
它正常工作。我试图在不使用事务的情况下创建死锁,但现在我没有更多的想法。我试图从存储过程spTransaction1和spTransaction2消除事务命令,我使用循环创建更多线程,但我没有像我预期的那样创建死锁。我没有很多并行编程的经验所以也许我做错了什么..是否有没有使用交易创建死锁的任何可能性?如果是,请写一些例子。如果您使用我的代码来解决这种情况,那将会很棒;) 谢谢!
答案 0 :(得分:0)
死锁是资源无法解决的冲突 - 需求B,B在一系列指令中需要A.没有交易,您只需运行一堆单个指令。它们可能会失败(或完成),但它们不会死锁,因为这些位之间没有依赖关系。