2015-11-15 86 views
1

我在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,我创建更多的线程使用循环,但我没有创建死锁,因为我的expect.I没有大的并行编程经验,所以也许我做了错误的..有没有可能不使用事务创建死锁?如果是,请写一些例子。如果你使用我的代码来解决这个问题,那将会很棒;) 谢谢!

回答

0

死锁是无法解决的资源冲突 - 需求B,B在指令序列中需要A.没有交易,你只是运行一堆单一的指令。它们可能会失败(或完成),但它们不会因为位之间没有依赖关系而死锁。

+0

所以没有这样的选项来创建死锁而不使用事务? – user4775372

+0

我想不出一个。因为从本质上讲,如果没有交易,死锁就需要一系列的操作,这里没有链条。这只是一系列不相关的单一操作(技术上不合逻辑)。 – LoztInSpace

相关问题