c# - SQL 数据库中的 Controller 异步/等待死锁

标签 c# asp.net-mvc asynchronous

我有一个 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/

相关文章:

php - 异步 PHP |将数据处理到多个系统中(建议)

c# - pdf呈现到asp.net网页导致静态标题

c# - Entity Framework 上的多个 .Where() 子句可查询

javascript - 返回 false 不适用于 MVC post

c# - 只应验证最小/最大长度

c# - 使用异步套接字的回调

c# - 将 int 转换为 short 的更好方法? (如果不可能则为 NULL)

c# - 在 C# 构造函数中处理可选委托(delegate)的最佳方法是什么?

asp.net-mvc - 如何使用 MVC 3 (Razor) 向图像添加动态源

node.js - 如何使用异步/等待从另一个函数访问请求的主体?