C# 同时向2个表插入API请求时发生数据库死锁

C# 同时向2个表插入API请求时发生数据库死锁,c#,sql-server,asp.net-core,.net-core,entity-framework-core,C#,Sql Server,Asp.net Core,.net Core,Entity Framework Core,所以我的api中有一个端点,它接受带有数据的文件。对于每个文件,我提取数据并将其保存到Products表中,同时保存添加到differentSavedFiles表中的文件名和日期。每个产品都有fileId,以便我们知道它来自哪个文件 在控制器的端点内,基本上有: await Handler.SaveFromFile(fileStream, fileName) 处理程序在Startup.cs中注册为services.addScope()并注入控制器 方法是这样构建的: public async

所以我的api中有一个端点,它接受带有数据的文件。对于每个文件,我提取数据并将其保存到
Products
表中,同时保存添加到different
SavedFiles
表中的文件名和日期。每个产品都有
fileId
,以便我们知道它来自哪个文件

在控制器的端点内,基本上有:

await Handler.SaveFromFile(fileStream, fileName)
处理程序在Startup.cs中注册为
services.addScope()并注入控制器

方法是这样构建的:

public async Task SaveFromFile(Stream fileStream, string fileName)
{
     List<Products> products = Extract(fileStream);
     var file = new SavedFile 
     {
          FileName = fileName,
          DateAdded = DateTime.UtcNow
     };

     foreach (var product in products)
     {
          product.SavedFile = file;
     }

     DbContext.AddRange(products);
     await DbContext.SaveChangesAsync();
}
我尝试设置
builder.EnableRetryOnFailure(5,TimeSpan.FromSeconds(10),null)但我得到了另一个例外:

System.InvalidOperationException: An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseSqlServer' call.
---> Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): Transaction (Process ID 55) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
 ---> Microsoft.Data.SqlClient.SqlException (0x80131904): The MERGE statement conflicted with the FOREIGN KEY constraint "FK_Products_SavedFiles_SavedFileId". The conflict occurred in database "TestDB", table "dbo.SavedFiles", column 'Id'.
如何避免这样的冲突? 实际上,对于具有不同数据的文件,我也有不同的端点。它们将数据保存到不同的表中,但有关文件的信息与其他端点保存到同一个表中,如果有对两个不同端点的请求,我会得到相同的异常(可能是因为它们都使用SavedFiles表),因此我需要跨所有端点工作的解决方案

@编辑:

[HttpPost("Upload")]
public async Task<ActionResult> Upload([FromForm]IFormFile file)
{
    if (file == null || file.Length == 0)
    {
        return BadRequest();
    }

    using var fileStream = file.OpenReadStream();

    await Handler.SaveFromFile(fileStream, file.FileName);

    return Ok();
}
    services.AddDbContext<TestDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), builder => 
    {
        builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    }));
<deadlock>
 <victim-list>
  <victimProcess id="process2026c423088" />
 </victim-list>
 <process-list>
  <process id="process2026c423088" taskpriority="0" logused="94536" waitresource="KEY: 7:72057594043236352 (5d937923d5a3)" waittime="3199" ownerId="6294993" transactionname="user_transaction" lasttranstarted="2020-08-26T15:23:12.940" XDES="0x2026ed30490" lockMode="S" schedulerid="3" kpid="21092" status="suspended" spid="66" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2020-08-26T15:23:14.487" lastbatchcompleted="2020-08-26T15:23:14.227" lastattention="1900-01-01T00:00:00.227" clientapp="Core Microsoft SqlClient Data Provider" hostname="DESKTOP" hostpid="18656" loginname="kamil" isolationlevel="read committed (2)" xactid="6294993" currentdb="7" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="3" stmtstart="73724" stmtend="110198" sqlhandle="0x02000000b605be0cf972a469745510a34ff7a63c7c992a5c0000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@p6 decimal(1,0),@p7 bigint,@p8 nvarchar(4000),@p9 decimal(2,2),@p10 nvarchar(4000),@p11 decimal(3,3),@p12 int,@p13 tinyint,@p14 decimal(1,0),@p15 bigint,@p16 nvarchar(4000),@p17 decimal(4,4),@p18 nvarchar(4000),@p19 decimal(5,5),@p20 int,@p21 tinyint,@p22 decimal(1,0),@p23 bigint,@p24 nvarchar(4000),@p25 decimal(5,4),@p26 nvarchar(4000),@p27 decimal(17,15),@p28 int,@p29 tinyint,@p30 decimal(1,0),@p31 bigint,@p32 nvarchar(4000),@p33 decimal(5,4),@p34 nvarchar(4000),@p35 decimal(17,15),@p36 int,@p37 tinyint,@p38 decimal(1,0),@p39 bigint,@p40 nvarchar(4000),@p41 decimal(5,4),@p42 nvarchar(4000),@p43 decimal(17,15),@p44 int,@p45 tinyint,@p46 decimal(1,0),@p47 bigint,@p48 nvarchar(4000),@p49 decimal(5,4),@p50 nvarchar(4000),@p51 decimal(17,15),@p52 int,@p53 tinyint,@p54 decimal(1,0),@p55 bigint,@p56 nvarchar(4000),@p57 decimal(5,4),@p58 nvarchar(4000),@p59 decimal(17,15),@p60 int,@p61 tinyint,@p62 decimal(1,0),@p63 bigint,@p64 nvarchar(4000),@p65 decimal(5,4),@p66 nvarchar(4000),@p67 decimal(17,15),@p68 int,@p6   </inputbuf>
  </process>
  <process id="process202715a5848" taskpriority="0" logused="855980" waitresource="KEY: 7:72057594043236352 (39c9529c1a80)" waittime="3841" ownerId="6294746" transactionname="user_transaction" lasttranstarted="2020-08-26T15:23:08.467" XDES="0x20269474490" lockMode="S" schedulerid="2" kpid="29744" status="suspended" spid="67" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2020-08-26T15:23:13.770" lastbatchcompleted="2020-08-26T15:23:13.757" lastattention="1900-01-01T00:00:00.757" clientapp="Core Microsoft SqlClient Data Provider" hostname="DESKTOP" hostpid="18656" loginname="kamil" isolationlevel="read committed (2)" xactid="6294746" currentdb="7" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="3" stmtstart="73728" stmtend="110166" sqlhandle="0x0200000045e14010c29c7110c8ba274a0810d01d7814e9f90000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@p0 decimal(1,0),@p1 bigint,@p2 nvarchar(4000),@p3 decimal(2,2),@p4 nvarchar(4000),@p5 decimal(3,3),@p6 int,@p7 tinyint,@p8 decimal(1,0),@p9 bigint,@p10 nvarchar(4000),@p11 decimal(3,2),@p12 nvarchar(4000),@p13 decimal(5,3),@p14 int,@p15 tinyint,@p16 decimal(1,0),@p17 bigint,@p18 nvarchar(4000),@p19 decimal(2,2),@p20 nvarchar(4000),@p21 decimal(4,3),@p22 int,@p23 tinyint,@p24 decimal(1,0),@p25 bigint,@p26 nvarchar(4000),@p27 decimal(3,2),@p28 nvarchar(4000),@p29 decimal(4,3),@p30 int,@p31 tinyint,@p32 decimal(1,0),@p33 bigint,@p34 nvarchar(4000),@p35 decimal(2,2),@p36 nvarchar(4000),@p37 decimal(17,17),@p38 int,@p39 tinyint,@p40 decimal(1,0),@p41 bigint,@p42 nvarchar(4000),@p43 decimal(2,2),@p44 nvarchar(4000),@p45 decimal(16,16),@p46 int,@p47 tinyint,@p48 decimal(1,0),@p49 bigint,@p50 nvarchar(4000),@p51 decimal(3,2),@p52 nvarchar(4000),@p53 decimal(17,15),@p54 int,@p55 tinyint,@p56 decimal(1,0),@p57 bigint,@p58 nvarchar(4000),@p59 decimal(3,2),@p60 nvarchar(4000),@p61 decimal(16,15),@p62 int,@p63 tinyint,   </inputbuf>
  </process>
 </process-list>
 <resource-list>
  <keylock hobtid="72057594043236352" dbid="7" objectname="TestDB.dbo.SavedFiles" indexname="PK_SavedFiles" id="lock20238cb3d80" mode="X" associatedObjectId="72057594043236352">
   <owner-list>
    <owner id="process202715a5848" mode="X" />
   </owner-list>
   <waiter-list>
    <waiter id="process2026c423088" mode="S" requestType="wait" />
   </waiter-list>
  </keylock>
  <keylock hobtid="72057594043236352" dbid="7" objectname="TestDB.dbo.SavedFiles" indexname="PK_SavedFiles" id="lock20279061100" mode="X" associatedObjectId="72057594043236352">
   <owner-list>
    <owner id="process2026c423088" mode="X" />
   </owner-list>
   <waiter-list>
    <waiter id="process202715a5848" mode="S" requestType="wait" />
   </waiter-list>
  </keylock>
 </resource-list>
</deadlock>

@大师斯特隆要求整个控制器的行动,并重试配置

控制器操作:

[HttpPost("Upload")]
public async Task<ActionResult> Upload([FromForm]IFormFile file)
{
    if (file == null || file.Length == 0)
    {
        return BadRequest();
    }

    using var fileStream = file.OpenReadStream();

    await Handler.SaveFromFile(fileStream, file.FileName);

    return Ok();
}
    services.AddDbContext<TestDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), builder => 
    {
        builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    }));
<deadlock>
 <victim-list>
  <victimProcess id="process2026c423088" />
 </victim-list>
 <process-list>
  <process id="process2026c423088" taskpriority="0" logused="94536" waitresource="KEY: 7:72057594043236352 (5d937923d5a3)" waittime="3199" ownerId="6294993" transactionname="user_transaction" lasttranstarted="2020-08-26T15:23:12.940" XDES="0x2026ed30490" lockMode="S" schedulerid="3" kpid="21092" status="suspended" spid="66" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2020-08-26T15:23:14.487" lastbatchcompleted="2020-08-26T15:23:14.227" lastattention="1900-01-01T00:00:00.227" clientapp="Core Microsoft SqlClient Data Provider" hostname="DESKTOP" hostpid="18656" loginname="kamil" isolationlevel="read committed (2)" xactid="6294993" currentdb="7" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="3" stmtstart="73724" stmtend="110198" sqlhandle="0x02000000b605be0cf972a469745510a34ff7a63c7c992a5c0000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@p6 decimal(1,0),@p7 bigint,@p8 nvarchar(4000),@p9 decimal(2,2),@p10 nvarchar(4000),@p11 decimal(3,3),@p12 int,@p13 tinyint,@p14 decimal(1,0),@p15 bigint,@p16 nvarchar(4000),@p17 decimal(4,4),@p18 nvarchar(4000),@p19 decimal(5,5),@p20 int,@p21 tinyint,@p22 decimal(1,0),@p23 bigint,@p24 nvarchar(4000),@p25 decimal(5,4),@p26 nvarchar(4000),@p27 decimal(17,15),@p28 int,@p29 tinyint,@p30 decimal(1,0),@p31 bigint,@p32 nvarchar(4000),@p33 decimal(5,4),@p34 nvarchar(4000),@p35 decimal(17,15),@p36 int,@p37 tinyint,@p38 decimal(1,0),@p39 bigint,@p40 nvarchar(4000),@p41 decimal(5,4),@p42 nvarchar(4000),@p43 decimal(17,15),@p44 int,@p45 tinyint,@p46 decimal(1,0),@p47 bigint,@p48 nvarchar(4000),@p49 decimal(5,4),@p50 nvarchar(4000),@p51 decimal(17,15),@p52 int,@p53 tinyint,@p54 decimal(1,0),@p55 bigint,@p56 nvarchar(4000),@p57 decimal(5,4),@p58 nvarchar(4000),@p59 decimal(17,15),@p60 int,@p61 tinyint,@p62 decimal(1,0),@p63 bigint,@p64 nvarchar(4000),@p65 decimal(5,4),@p66 nvarchar(4000),@p67 decimal(17,15),@p68 int,@p6   </inputbuf>
  </process>
  <process id="process202715a5848" taskpriority="0" logused="855980" waitresource="KEY: 7:72057594043236352 (39c9529c1a80)" waittime="3841" ownerId="6294746" transactionname="user_transaction" lasttranstarted="2020-08-26T15:23:08.467" XDES="0x20269474490" lockMode="S" schedulerid="2" kpid="29744" status="suspended" spid="67" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2020-08-26T15:23:13.770" lastbatchcompleted="2020-08-26T15:23:13.757" lastattention="1900-01-01T00:00:00.757" clientapp="Core Microsoft SqlClient Data Provider" hostname="DESKTOP" hostpid="18656" loginname="kamil" isolationlevel="read committed (2)" xactid="6294746" currentdb="7" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="3" stmtstart="73728" stmtend="110166" sqlhandle="0x0200000045e14010c29c7110c8ba274a0810d01d7814e9f90000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@p0 decimal(1,0),@p1 bigint,@p2 nvarchar(4000),@p3 decimal(2,2),@p4 nvarchar(4000),@p5 decimal(3,3),@p6 int,@p7 tinyint,@p8 decimal(1,0),@p9 bigint,@p10 nvarchar(4000),@p11 decimal(3,2),@p12 nvarchar(4000),@p13 decimal(5,3),@p14 int,@p15 tinyint,@p16 decimal(1,0),@p17 bigint,@p18 nvarchar(4000),@p19 decimal(2,2),@p20 nvarchar(4000),@p21 decimal(4,3),@p22 int,@p23 tinyint,@p24 decimal(1,0),@p25 bigint,@p26 nvarchar(4000),@p27 decimal(3,2),@p28 nvarchar(4000),@p29 decimal(4,3),@p30 int,@p31 tinyint,@p32 decimal(1,0),@p33 bigint,@p34 nvarchar(4000),@p35 decimal(2,2),@p36 nvarchar(4000),@p37 decimal(17,17),@p38 int,@p39 tinyint,@p40 decimal(1,0),@p41 bigint,@p42 nvarchar(4000),@p43 decimal(2,2),@p44 nvarchar(4000),@p45 decimal(16,16),@p46 int,@p47 tinyint,@p48 decimal(1,0),@p49 bigint,@p50 nvarchar(4000),@p51 decimal(3,2),@p52 nvarchar(4000),@p53 decimal(17,15),@p54 int,@p55 tinyint,@p56 decimal(1,0),@p57 bigint,@p58 nvarchar(4000),@p59 decimal(3,2),@p60 nvarchar(4000),@p61 decimal(16,15),@p62 int,@p63 tinyint,   </inputbuf>
  </process>
 </process-list>
 <resource-list>
  <keylock hobtid="72057594043236352" dbid="7" objectname="TestDB.dbo.SavedFiles" indexname="PK_SavedFiles" id="lock20238cb3d80" mode="X" associatedObjectId="72057594043236352">
   <owner-list>
    <owner id="process202715a5848" mode="X" />
   </owner-list>
   <waiter-list>
    <waiter id="process2026c423088" mode="S" requestType="wait" />
   </waiter-list>
  </keylock>
  <keylock hobtid="72057594043236352" dbid="7" objectname="TestDB.dbo.SavedFiles" indexname="PK_SavedFiles" id="lock20279061100" mode="X" associatedObjectId="72057594043236352">
   <owner-list>
    <owner id="process2026c423088" mode="X" />
   </owner-list>
   <waiter-list>
    <waiter id="process202715a5848" mode="S" requestType="wait" />
   </waiter-list>
  </keylock>
 </resource-list>
</deadlock>

[HttpPost(“上传”)]
公共异步任务上载([FromForm]格式文件)
{
if(file==null | | file.Length==0)
{
返回请求();
}
使用var fileStream=file.OpenReadStream();
wait Handler.SaveFromFile(fileStream,file.FileName);
返回Ok();
}
我尝试在启动中设置重试。cs:

[HttpPost("Upload")]
public async Task<ActionResult> Upload([FromForm]IFormFile file)
{
    if (file == null || file.Length == 0)
    {
        return BadRequest();
    }

    using var fileStream = file.OpenReadStream();

    await Handler.SaveFromFile(fileStream, file.FileName);

    return Ok();
}
    services.AddDbContext<TestDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), builder => 
    {
        builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    }));
<deadlock>
 <victim-list>
  <victimProcess id="process2026c423088" />
 </victim-list>
 <process-list>
  <process id="process2026c423088" taskpriority="0" logused="94536" waitresource="KEY: 7:72057594043236352 (5d937923d5a3)" waittime="3199" ownerId="6294993" transactionname="user_transaction" lasttranstarted="2020-08-26T15:23:12.940" XDES="0x2026ed30490" lockMode="S" schedulerid="3" kpid="21092" status="suspended" spid="66" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2020-08-26T15:23:14.487" lastbatchcompleted="2020-08-26T15:23:14.227" lastattention="1900-01-01T00:00:00.227" clientapp="Core Microsoft SqlClient Data Provider" hostname="DESKTOP" hostpid="18656" loginname="kamil" isolationlevel="read committed (2)" xactid="6294993" currentdb="7" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="3" stmtstart="73724" stmtend="110198" sqlhandle="0x02000000b605be0cf972a469745510a34ff7a63c7c992a5c0000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@p6 decimal(1,0),@p7 bigint,@p8 nvarchar(4000),@p9 decimal(2,2),@p10 nvarchar(4000),@p11 decimal(3,3),@p12 int,@p13 tinyint,@p14 decimal(1,0),@p15 bigint,@p16 nvarchar(4000),@p17 decimal(4,4),@p18 nvarchar(4000),@p19 decimal(5,5),@p20 int,@p21 tinyint,@p22 decimal(1,0),@p23 bigint,@p24 nvarchar(4000),@p25 decimal(5,4),@p26 nvarchar(4000),@p27 decimal(17,15),@p28 int,@p29 tinyint,@p30 decimal(1,0),@p31 bigint,@p32 nvarchar(4000),@p33 decimal(5,4),@p34 nvarchar(4000),@p35 decimal(17,15),@p36 int,@p37 tinyint,@p38 decimal(1,0),@p39 bigint,@p40 nvarchar(4000),@p41 decimal(5,4),@p42 nvarchar(4000),@p43 decimal(17,15),@p44 int,@p45 tinyint,@p46 decimal(1,0),@p47 bigint,@p48 nvarchar(4000),@p49 decimal(5,4),@p50 nvarchar(4000),@p51 decimal(17,15),@p52 int,@p53 tinyint,@p54 decimal(1,0),@p55 bigint,@p56 nvarchar(4000),@p57 decimal(5,4),@p58 nvarchar(4000),@p59 decimal(17,15),@p60 int,@p61 tinyint,@p62 decimal(1,0),@p63 bigint,@p64 nvarchar(4000),@p65 decimal(5,4),@p66 nvarchar(4000),@p67 decimal(17,15),@p68 int,@p6   </inputbuf>
  </process>
  <process id="process202715a5848" taskpriority="0" logused="855980" waitresource="KEY: 7:72057594043236352 (39c9529c1a80)" waittime="3841" ownerId="6294746" transactionname="user_transaction" lasttranstarted="2020-08-26T15:23:08.467" XDES="0x20269474490" lockMode="S" schedulerid="2" kpid="29744" status="suspended" spid="67" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2020-08-26T15:23:13.770" lastbatchcompleted="2020-08-26T15:23:13.757" lastattention="1900-01-01T00:00:00.757" clientapp="Core Microsoft SqlClient Data Provider" hostname="DESKTOP" hostpid="18656" loginname="kamil" isolationlevel="read committed (2)" xactid="6294746" currentdb="7" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="3" stmtstart="73728" stmtend="110166" sqlhandle="0x0200000045e14010c29c7110c8ba274a0810d01d7814e9f90000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@p0 decimal(1,0),@p1 bigint,@p2 nvarchar(4000),@p3 decimal(2,2),@p4 nvarchar(4000),@p5 decimal(3,3),@p6 int,@p7 tinyint,@p8 decimal(1,0),@p9 bigint,@p10 nvarchar(4000),@p11 decimal(3,2),@p12 nvarchar(4000),@p13 decimal(5,3),@p14 int,@p15 tinyint,@p16 decimal(1,0),@p17 bigint,@p18 nvarchar(4000),@p19 decimal(2,2),@p20 nvarchar(4000),@p21 decimal(4,3),@p22 int,@p23 tinyint,@p24 decimal(1,0),@p25 bigint,@p26 nvarchar(4000),@p27 decimal(3,2),@p28 nvarchar(4000),@p29 decimal(4,3),@p30 int,@p31 tinyint,@p32 decimal(1,0),@p33 bigint,@p34 nvarchar(4000),@p35 decimal(2,2),@p36 nvarchar(4000),@p37 decimal(17,17),@p38 int,@p39 tinyint,@p40 decimal(1,0),@p41 bigint,@p42 nvarchar(4000),@p43 decimal(2,2),@p44 nvarchar(4000),@p45 decimal(16,16),@p46 int,@p47 tinyint,@p48 decimal(1,0),@p49 bigint,@p50 nvarchar(4000),@p51 decimal(3,2),@p52 nvarchar(4000),@p53 decimal(17,15),@p54 int,@p55 tinyint,@p56 decimal(1,0),@p57 bigint,@p58 nvarchar(4000),@p59 decimal(3,2),@p60 nvarchar(4000),@p61 decimal(16,15),@p62 int,@p63 tinyint,   </inputbuf>
  </process>
 </process-list>
 <resource-list>
  <keylock hobtid="72057594043236352" dbid="7" objectname="TestDB.dbo.SavedFiles" indexname="PK_SavedFiles" id="lock20238cb3d80" mode="X" associatedObjectId="72057594043236352">
   <owner-list>
    <owner id="process202715a5848" mode="X" />
   </owner-list>
   <waiter-list>
    <waiter id="process2026c423088" mode="S" requestType="wait" />
   </waiter-list>
  </keylock>
  <keylock hobtid="72057594043236352" dbid="7" objectname="TestDB.dbo.SavedFiles" indexname="PK_SavedFiles" id="lock20279061100" mode="X" associatedObjectId="72057594043236352">
   <owner-list>
    <owner id="process2026c423088" mode="X" />
   </owner-list>
   <waiter-list>
    <waiter id="process202715a5848" mode="S" requestType="wait" />
   </waiter-list>
  </keylock>
 </resource-list>
</deadlock>

services.AddDbContext(options=>options.UseSqlServer(Configuration.GetConnectionString(“DefaultConnection”),builder=>
{
builder.EnableRetryOnFailure(5,TimeSpan.FromSeconds(10),null);
}));
@丹·古兹曼询问死锁信息

来自系统运行状况跟踪的死锁信息:

[HttpPost("Upload")]
public async Task<ActionResult> Upload([FromForm]IFormFile file)
{
    if (file == null || file.Length == 0)
    {
        return BadRequest();
    }

    using var fileStream = file.OpenReadStream();

    await Handler.SaveFromFile(fileStream, file.FileName);

    return Ok();
}
    services.AddDbContext<TestDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), builder => 
    {
        builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    }));
<deadlock>
 <victim-list>
  <victimProcess id="process2026c423088" />
 </victim-list>
 <process-list>
  <process id="process2026c423088" taskpriority="0" logused="94536" waitresource="KEY: 7:72057594043236352 (5d937923d5a3)" waittime="3199" ownerId="6294993" transactionname="user_transaction" lasttranstarted="2020-08-26T15:23:12.940" XDES="0x2026ed30490" lockMode="S" schedulerid="3" kpid="21092" status="suspended" spid="66" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2020-08-26T15:23:14.487" lastbatchcompleted="2020-08-26T15:23:14.227" lastattention="1900-01-01T00:00:00.227" clientapp="Core Microsoft SqlClient Data Provider" hostname="DESKTOP" hostpid="18656" loginname="kamil" isolationlevel="read committed (2)" xactid="6294993" currentdb="7" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="3" stmtstart="73724" stmtend="110198" sqlhandle="0x02000000b605be0cf972a469745510a34ff7a63c7c992a5c0000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@p6 decimal(1,0),@p7 bigint,@p8 nvarchar(4000),@p9 decimal(2,2),@p10 nvarchar(4000),@p11 decimal(3,3),@p12 int,@p13 tinyint,@p14 decimal(1,0),@p15 bigint,@p16 nvarchar(4000),@p17 decimal(4,4),@p18 nvarchar(4000),@p19 decimal(5,5),@p20 int,@p21 tinyint,@p22 decimal(1,0),@p23 bigint,@p24 nvarchar(4000),@p25 decimal(5,4),@p26 nvarchar(4000),@p27 decimal(17,15),@p28 int,@p29 tinyint,@p30 decimal(1,0),@p31 bigint,@p32 nvarchar(4000),@p33 decimal(5,4),@p34 nvarchar(4000),@p35 decimal(17,15),@p36 int,@p37 tinyint,@p38 decimal(1,0),@p39 bigint,@p40 nvarchar(4000),@p41 decimal(5,4),@p42 nvarchar(4000),@p43 decimal(17,15),@p44 int,@p45 tinyint,@p46 decimal(1,0),@p47 bigint,@p48 nvarchar(4000),@p49 decimal(5,4),@p50 nvarchar(4000),@p51 decimal(17,15),@p52 int,@p53 tinyint,@p54 decimal(1,0),@p55 bigint,@p56 nvarchar(4000),@p57 decimal(5,4),@p58 nvarchar(4000),@p59 decimal(17,15),@p60 int,@p61 tinyint,@p62 decimal(1,0),@p63 bigint,@p64 nvarchar(4000),@p65 decimal(5,4),@p66 nvarchar(4000),@p67 decimal(17,15),@p68 int,@p6   </inputbuf>
  </process>
  <process id="process202715a5848" taskpriority="0" logused="855980" waitresource="KEY: 7:72057594043236352 (39c9529c1a80)" waittime="3841" ownerId="6294746" transactionname="user_transaction" lasttranstarted="2020-08-26T15:23:08.467" XDES="0x20269474490" lockMode="S" schedulerid="2" kpid="29744" status="suspended" spid="67" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2020-08-26T15:23:13.770" lastbatchcompleted="2020-08-26T15:23:13.757" lastattention="1900-01-01T00:00:00.757" clientapp="Core Microsoft SqlClient Data Provider" hostname="DESKTOP" hostpid="18656" loginname="kamil" isolationlevel="read committed (2)" xactid="6294746" currentdb="7" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="3" stmtstart="73728" stmtend="110166" sqlhandle="0x0200000045e14010c29c7110c8ba274a0810d01d7814e9f90000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@p0 decimal(1,0),@p1 bigint,@p2 nvarchar(4000),@p3 decimal(2,2),@p4 nvarchar(4000),@p5 decimal(3,3),@p6 int,@p7 tinyint,@p8 decimal(1,0),@p9 bigint,@p10 nvarchar(4000),@p11 decimal(3,2),@p12 nvarchar(4000),@p13 decimal(5,3),@p14 int,@p15 tinyint,@p16 decimal(1,0),@p17 bigint,@p18 nvarchar(4000),@p19 decimal(2,2),@p20 nvarchar(4000),@p21 decimal(4,3),@p22 int,@p23 tinyint,@p24 decimal(1,0),@p25 bigint,@p26 nvarchar(4000),@p27 decimal(3,2),@p28 nvarchar(4000),@p29 decimal(4,3),@p30 int,@p31 tinyint,@p32 decimal(1,0),@p33 bigint,@p34 nvarchar(4000),@p35 decimal(2,2),@p36 nvarchar(4000),@p37 decimal(17,17),@p38 int,@p39 tinyint,@p40 decimal(1,0),@p41 bigint,@p42 nvarchar(4000),@p43 decimal(2,2),@p44 nvarchar(4000),@p45 decimal(16,16),@p46 int,@p47 tinyint,@p48 decimal(1,0),@p49 bigint,@p50 nvarchar(4000),@p51 decimal(3,2),@p52 nvarchar(4000),@p53 decimal(17,15),@p54 int,@p55 tinyint,@p56 decimal(1,0),@p57 bigint,@p58 nvarchar(4000),@p59 decimal(3,2),@p60 nvarchar(4000),@p61 decimal(16,15),@p62 int,@p63 tinyint,   </inputbuf>
  </process>
 </process-list>
 <resource-list>
  <keylock hobtid="72057594043236352" dbid="7" objectname="TestDB.dbo.SavedFiles" indexname="PK_SavedFiles" id="lock20238cb3d80" mode="X" associatedObjectId="72057594043236352">
   <owner-list>
    <owner id="process202715a5848" mode="X" />
   </owner-list>
   <waiter-list>
    <waiter id="process2026c423088" mode="S" requestType="wait" />
   </waiter-list>
  </keylock>
  <keylock hobtid="72057594043236352" dbid="7" objectname="TestDB.dbo.SavedFiles" indexname="PK_SavedFiles" id="lock20279061100" mode="X" associatedObjectId="72057594043236352">
   <owner-list>
    <owner id="process2026c423088" mode="X" />
   </owner-list>
   <waiter-list>
    <waiter id="process202715a5848" mode="S" requestType="wait" />
   </waiter-list>
  </keylock>
 </resource-list>
</deadlock>


不为人知
不为人知
(@p6十进制数(1,0),@p7-bigint,@p8-nvarchar(4000),@p9十进制数(2,2),@p10-nvarchar(4000),@p11十进制数(3,3),@p12-int,@p13-tinyint,@p14十进制数(1,0),@p15-bigint,@p16-nvarchar(4000),@p17十进制数(4,4),@p18-nvarchar(4000),@p19十进制数(5,5),@p20-int,@p21-tinyint,@p22十进制数(1,0),@p23-bigint,@p24-nvarcharcharcharcharchar),p25-nvarcharcharcharcharcharcharchar(4000),@p25,4000),@p24十进制数),@p27十进制(17,15),@p28 int,@p29 tinyint,@p30 decimal(1,0),@p31 bigint,@p32 nvarchar(4000),@p33 decimal(5,4),@p34 nvarchar(4000),@p35 decimal(17,15),@p36 int,@p37 tinyint,@p38 decimal(1,0),@p39 bigint,@p40 nvarchar(4000),@p41 decimal(5,4),@p42 nvarchar)nvarchar(4000),@p43 decimal,17,15),@p44 tinyint,@p45 tinyint,nvarcharchar,@p41,8(4000),@p49十进制(5,4),@p50 nvarchar(4000),@p51十进制(17,15),@p52 int,@p53 tinyint,@p54十进制(1,0),@p55 bigint,@p56 nvarchar(4000),@p57十进制(5,4),@p58 nvarchar(4000),@p59十进制(17,15),@p60 int,@p61 tinyint,@p62十进制(1,0),@p63 bigint,@p64 nvarchar(4000),@p65十进制(5,4),@p66 nvarchar),@p67 nvarchar),@p67十进制(4000),@p68),@p68,17,@p68,@p68,17,17,17
不为人知
不为人知
(@p0十进制(1,0),@p1-bigint,@p2-nvarchar(4000),@p3十进制(2,2),@p4-nvarchar(4000),@p5十进制(3,3),@p6-int,@p7-tinyint,@p8十进制(1,0),@p9-bigint,@p10-nvarchar(4000),@p11十进制(3,2),@p12-nvarcharchar十进制(4000),@p13十进制(5,3),@p14-int,@p15-tinyint,@p16十进制(1,0),@p17-bigint,@p18-nvarcharcharcharchar(4000),@p18-nvarcharcharcharcharcharcharcharcharchar),@p12,4000),@p12,p20),@p19十进制,(p12),@p11,4000),@p1(4,3),@p22 int,@p23 tinyint,@p24 decimal(1,0),@p25 bigint,@p26 nvarchar(4000),@p27 decimal(3,2),@p28 nvarchar(4000),@p29 decimal(4,3),@p30 int,@p31 tinyint,@p32 decimal(1,0),@p33 bigint,@p34 nvarchar(4000),@p35 decimal(2,2),@p36 nvarchar(4000),@p37 decimal)(17,17),@p38 int,@p39 tinyint,@p39 tinyint,@p34 nvarcharcharchar,(4000),@p41,4)decimal,@p41,4000),@p42 decimal,@p41,3(2,2),@p44-nvarchar(4000),@p45-decimal(16,16),@p46-int,@p47-tinyint,@p48-decimal(1,0),@p49-bigint,@p50-nvarchar(4000),@p51-decimal(3,2),@p52-nvarchar(4000),@p53-decimal(17,15),@p54-tinyint,@p56-decimal(1,0),@p57-bigint,@p58-nvarchar(4000),@p59-decimal)(3,2),@p60-nvarchar(4000),@p60-nvarchar),decimal(4000),@p61-decimal)(16,15),@p62,@p62,

您可以使用锁定语句

简单的例子:

private static object lockPad = new object(); 

[HttpPost("Upload")]

public async Task Upload([FromForm]IFormFile file) 
{ 
  if (file == null || file.Length == 0) 
  { 
    return BadRequest(); 
  }

  using var fileStream = file.OpenReadStream();

  lock (lockPad)
  {
    await Handler.SaveFromFile(fileStream, file.FileName);
  }

  return Ok();
}

您能添加整个控制器操作和重试尝试吗?关于避免死锁,查询索引优化通常有助于最小化所接触的数据。如果需要帮助,请将执行计划上载到。此外,您还可以确定死锁资源。@Guruston我编辑了我的文章,包括了整个控制器和重试配置。@DanGuzman我从system_health trace(未设置重试时)中包含死锁信息。我不太明白执行计划是什么意思。您的问题已经在这里得到了回答:我不确定它是否对一个控制器有帮助,但即使有帮助,不同控制器(不同类)之间仍然存在冲突插入到同一个表中的死锁发生在SQL级别,而不是主机语言,而且它运行在API级别,因此每个请求都有自己的死锁context@kkamil4sz这只是一个简单的示例,您可以在其他位置(例如Startup.cs)拥有一个公共和静态锁,并在将其插入此表时使用它。