2015-11-15 3 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, и я создаю больше потоков с использованием цикла, но я не создал тупик, как я и ожидал. У меня нет большого опыта в параллельном программировании, поэтому, возможно, я сделал что-то не так. Есть ли возможность создать тупик без использования транзакции? Если да, напишите, пожалуйста, пример. Будет здорово, если вы будете использовать мой код для решения этого вопроса;) Спасибо!

ответ

0

Тупики - неразрешимые конфликты для ресурсов. Потребности B, B нуждаются в A во время последовательности инструкций. Без транзакций вы просто запускаете несколько инструкций. Они могут терпеть неудачу (или завершить), но они не будут заторможены, потому что между битами нет зависимости.

+0

Таким образом, нет такой возможности для создания взаимоблокировки без использования транзакции? – user4775372

+0

Я не могу придумать. Потому что по своей природе тупик требует цепочки операций, если нет транзакции, нет цепи. Это всего лишь серия одиночных операций, которые не связаны (технически, если не логически). – LoztInSpace

Смежные вопросы