实体框架事务中的死锁

时间:2016-04-15 07:51:21

标签: sql-server entity-framework deadlock sql-server-2014

我有一个小程序,它使用了Entity Framework。我以下面的方式使用它们。

  1. 在数据库中创建过程。
  2. 在实体框架中进行交易。
  3. 调用该事务中的过程。
  4. 这不可能更简单。但是,我怀疑是否有可能死锁?我的代码列在下面。

    void AddA()
    {
        using (var db = new Entities())
        {
            using (var tran = db.Database.BeginTransaction())
            {
                db.Add_A("helloA");
                Thread.Sleep(5000);
                db.Add_B("helloB");
                tran.Commit();
            }
        } 
    }
    
    void AddB()
    {
        using (var db = new Entities())
        {
            using (var tran = db.Database.BeginTransaction())
            {
                db.Add_B("helloB");
                Thread.Sleep(5000);
                db.Add_A("helloA");
                tran.Commit();
            }
        } 
    }
    

    Add_AAdd_B是此处的程序。

    从我的角度来看,这两种方法在同时调用时会导致死锁,因为它们以不同的顺序占用表。

    然而,当我做一些测试时,死锁并没有发生。这有什么不对?我做错了什么或没有死锁的风险?

    欢迎任何反馈。提前致谢。

    PS:我正在使用SQL Server 2014和Entity Framework 6.0。

1 个答案:

答案 0 :(得分:0)

从问题不清楚程序正在做什么。只有当Add_A和Add_B都包含一个声明时,如果多次调用,则会发生不兼容的锁定,从而发生死锁。

例如,如果Add_A和Add_B都运行select语句(在默认隔离级别read committed下),则不会发生死锁,因为select语句只会放置一个与其他线程放置的另一个共享锁兼容的共享锁。如果Add_A和Add_B包含update语句,则会发生死锁(当您同时或不同时间但小于延迟时运行时),因为update语句将对与另一个独占锁不兼容的对象进行独占锁定。