Sql server 实体框架事务中的死锁

Sql server 实体框架事务中的死锁,sql-server,entity-framework,deadlock,sql-server-2014,Sql Server,Entity Framework,Deadlock,Sql Server 2014,我有一个小程序,它利用实体框架。我用下面的方式使用它们 在数据库中创建过程 在实体框架中进行事务处理 调用该事务中的过程 这再简单不过了。但是,我怀疑是否有可能出现僵局?我的代码列表如下 void AddA() { using (var db = new Entities()) { using (var tran = db.Database.BeginTransaction()) { db.Add_A("helloA");

我有一个小程序,它利用实体框架。我用下面的方式使用它们

  • 在数据库中创建过程
  • 在实体框架中进行事务处理
  • 调用该事务中的过程 这再简单不过了。但是,我怀疑是否有可能出现僵局?我的代码列表如下

    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_A
    Add_B
    是这里的过程

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

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

    欢迎任何反馈。提前谢谢


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

    从问题中不清楚这些过程在做什么。只有当Add_A和Add_B都包含放置锁的语句时,死锁才会发生。如果多次调用该语句,该锁将不兼容


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

    问题不清楚这些过程在做什么。只有当Add_A和Add_B都包含放置锁的语句时,死锁才会发生。如果多次调用该语句,该锁将不兼容


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

    如何调用AddA和AddB?因为如果它只是顺序的,您将永远不会冲突为什么要使用事务<代码>保存更改已使用事务。如果您在每个
    Add
    方法中保存,则说明您做得不对。您应该将所需的所有实体添加到上下文中,然后调用SaveChangesonce@AllanS.Hansen嗯,我同时给AddA和AddB打了电话,据我所知,这可能有问题,因为AddA先占用表A,而AddB先占用表B,他们渴望占用另一张已经被对方占用的表。@AllanS.Hansen Well,我同时给AddA和AddB打了电话,据我所知,这可能有问题,因为AddA先占用表A,而AddB先占用表B,他们渴望占用另一张已经被对方占用的表。@PanagiotisKanavos感谢您的帮助。但我为什么在这里使用过程是因为过程中有一些逻辑。所以,毕竟我想要实现的是创建一个包含多个过程的事务,并且不发生任何死锁。我在数据库方面有点傻,所以我知道这不是一个好方法。你有更好的方法吗?你怎么称呼AddA和AddB?因为如果它只是顺序的,您将永远不会冲突为什么要使用事务<代码>保存更改已使用事务。如果您在每个
    Add
    方法中保存,则说明您做得不对。您应该将所需的所有实体添加到上下文中,然后调用SaveChangesonce@AllanS.Hansen嗯,我同时给AddA和AddB打了电话,据我所知,这可能有问题,因为AddA先占用表A,而AddB先占用表B,他们渴望占用另一张已经被对方占用的表。@AllanS.Hansen Well,我同时给AddA和AddB打了电话,据我所知,这可能有问题,因为AddA先占用表A,而AddB先占用表B,他们渴望占用另一张已经被对方占用的表。@PanagiotisKanavos感谢您的帮助。但我为什么在这里使用过程是因为过程中有一些逻辑。所以,毕竟我想要实现的是创建一个包含多个过程的事务,并且不发生任何死锁。我在数据库方面有点傻,所以我知道这不是一个好方法。你有更好的方法吗?