Chosen as the deadlock victim on simple Add() -> SaveChanges()

0

This simple program

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; }
}

Throws an exception like

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.

The SQL table looks like this in SSMS

TestEntities table from SSMS

c#
sql-server
entity-framework
ssms

1 Answer

0

As seen in the SSMS screenshot, there seem to be no indication of a primary key. There should have been a key symbol next to the ID column.

Some ID actually declared as primary key

Further inspection reveals that Id is indeed declared as identity (SQL Server for AUTO INCREMENT), but not as primary key. To make Id a real primary key right click the table in SSMS and choose Design, right click the Id row in the column designer and click SET PRIMARY KEY:

enter image description here

After this, the stress tests runs without deadlocking itself.


User contributions licensed under CC BY-SA 3.0