如何在不使用事务的情况下创建死锁?

时间:2015-11-15 11:45:32

标签: c# tsql

我在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消除事务命令,我使用循环创建更多线程,但我没有像我预期的那样创建死锁。我没有很多并行编程的经验所以也许我做错了什么..是否有没有使用交易创建死锁的任何可能性?如果是,请写一些例子。如果您使用我的代码来解决这种情况,那将会很棒;) 谢谢!

1 个答案:

答案 0 :(得分:0)

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