2017-07-12 15 views
1

コントローラが複数のマシンから複数のPOST(1分間に1000個)を受け取るため、これらのデータがすべてSQLデータベースに挿入されず、デッドロックが発生する。コントローラasync/SQLデータベースのデッドロックを待つ

どのようにして、このメソッドを同期して同時に使用するのではなく、後で挿入することができますか?

私は、このテストコントローラーで問題を再現することができる午前:

[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(); 
} 

EDIT:このコードは、魔法のように、ピーターの答えのおかげで働きました。デッドロックはありません。パフォーマンスは良好であり、遅さは気づかれませんでした。

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(); 
} 
+0

なぜタスクを待っているときに 'ConfigureAwait(false)'を使用していませんか? –

+2

@PeterBruins 'ConfigureAwait'には何が関係していますか?また、opは、.NETコードではなくSQL Serverのデッドロックについて話しています。また、 'ConfigureAwait'はすべての問題の解決策ではありません。 –

+0

あなたはdb.SaveChangesAsync()を待っているのですか?ConfigureAwait(false)?私は試してあなたに知らせるでしょう。 – expirat001

答えて

1

SemaphoreSlimを使用して、データベースへのアクセスを制限することができます。このセマフォは、非同期で待つことができます。

SemaphoreSlim semaphore = new SemaphoreSlim(1,1);  

public async Task<ActionResult> Create([Bind(Include = "Value1,Value2,Id")] Test test) 
{ 
    await semaphore.WaitAsync().ConfigureAwait(false); 
    if (ModelState.IsValid) 
    { 
     db.AuditTests.Add(test); 
     await db.SaveChangesAsync().ConfigureAwait(false); 
    } 
    semaphore.release(); 
    return new EmptyResult(); 
} 
+0

Peterに感謝します。自分のコードにSemaphoreSlimを実装する方法を教えてもらえますか? – expirat001

+0

私は今試して、結果を更新します。 – expirat001

+0

それは魅力のように働いて、20,000件の投稿と20,000件のレコードをDBに保存しました。 – expirat001

関連する問題