Я создаю простое консольное приложение в 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, и я создаю больше потоков с использованием цикла, но я не создал тупик, как я и ожидал. У меня нет большого опыта в параллельном программировании, поэтому, возможно, я сделал что-то не так. Есть ли возможность создать тупик без использования транзакции? Если да, напишите, пожалуйста, пример. Будет здорово, если вы будете использовать мой код для решения этого вопроса;) Спасибо!
Таким образом, нет такой возможности для создания взаимоблокировки без использования транзакции? – user4775372
Я не могу придумать. Потому что по своей природе тупик требует цепочки операций, если нет транзакции, нет цепи. Это всего лишь серия одиночных операций, которые не связаны (технически, если не логически). – LoztInSpace