2015-11-15 140 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

相關問題