在简单的Add()-> SaveChanges()上被选为死锁受害者

时间:2018-09-11 12:32:53

标签: c# sql-server entity-framework ssms

这个简单的程序

private static void Main(string[] args)
{
    Parallel.For(0, 1000000, InsertTestEntity);
}

private static void InsertTestEntity(int i)
{
    using (var dbContext = new TestDbContext())
    {
        dbContext.TestEntities.Add(new TestEntity { HugeString = "Baby shark," + string.Join(", ", Enumerable.Repeat("doo", 500)) });
        dbContext.SaveChanges();
    }
}

public class TestEntity
{
    [Key]
    public int Id { get; set; }

    public string HugeString { get; set; }
}

public class TestDbContext : DbContext
{
    public DbSet<TestEntity> TestEntities { get; set; }
}

引发类似

的异常
System.Data.Entity.Infrastructure.DbUpdateException
  HResult=0x80131501
  Message=An error occurred while updating the entries. See the inner exception for details.
  Source=EntityFramework
  StackTrace:
   at System.Data.Entity.Internal.InternalContext.SaveChanges()
   at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
   at System.Data.Entity.DbContext.SaveChanges()
   at EntityFrameworkStressTest.Program.InsertTestEntity(Int32 i) in c:\Git\EntityFrameworkStressTest\EntityFrameworkStressTest\Program.cs:line 18
   at System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.<ForWorker>b__1()

Inner Exception 1:
UpdateException: An error occurred while updating the entries. See the inner exception for details.

Inner Exception 2:
SqlException: Transaction (Process ID 100) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

SQL表在SSMS中看起来像这样

TestEntities table from SSMS

1 个答案:

答案 0 :(得分:0)

从SSMS屏幕截图中可以看出,似乎没有主键的迹象。 ID列旁边应该有一个钥匙符号。

Some ID actually declared as primary key

进一步检查发现,Id的确声明为身份(用于AUTO INCREMENT的SQL Server),但未声明为主键。要使Id成为真正的主键,请右键单击SSMS中的表,然后选择“设计”,右键单击列设计器中的Id行,然后单击“设置主键”:

enter image description here

此后,压力测试将运行而不会死锁。