我有一个 Controller 从多台机器接收多个 POST(每分钟 1000 个),因此所有这些数据都没有插入 SQL 数据库并生成一些死锁。
如何锁定此方法以同步使用以逐个插入而不是同时插入所有内容?
我能够使用此测试 Controller 重现该问题:
[HttpPost]
public async Task<ActionResult> Create([Bind(Include = "Value1,Value2,Id")] Test test)
{
if (ModelState.IsValid)
{
db.Tests.Add(test);
await db.SaveChangesAsync();
}
return new EmptyResult();
}
编辑:由于彼得的回答,这段代码非常有效。没有僵局。性能良好,没有注意到速度缓慢。
private SemaphoreSlim _semaphore = new SemaphoreSlim(1);
[HttpPost]
public async Task<ActionResult> Create([Bind(Include = "Value1,Value2,Id")] Test test)
{
await _semaphore.WaitAsync();
if (ModelState.IsValid)
{
db.Tests.Add(test);
await db.SaveChangesAsync().ConfigureAwait(false);
}
_semaphore.Release();
db.Dispose();
return new EmptyResult();
}
最佳答案
您可以使用SemaphoreSlim
来限制对数据库的访问。该信号量可以异步等待。
SemaphoreSlim semaphore = new SemaphoreSlim(1,1);
public async Task<ActionResult> Create([Bind(Include = "Value1,Value2,Id")] Test test)
{
try{
await semaphore.WaitAsync().ConfigureAwait(false);
if (ModelState.IsValid)
{
db.AuditTests.Add(test);
await db.SaveChangesAsync().ConfigureAwait(false);
}
}finally{
semaphore.release();
}
return new EmptyResult();
}
try
-finally
用于确保锁始终被释放,即使例如数据库调用失败。
关于c# - SQL 数据库中的 Controller 异步/等待死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45056392/