2017-07-12 3 views
1

Ich habe einen Controller, der mehrere POST (1000 pro Minute) von mehreren Rechnern erhält und deshalb werden diese Daten nicht in die SQL-Datenbank eingefügt und erzeugen einige Deadlocks.Controller async/Warten auf Deadlock in der SQL-Datenbank

Wie kann ich diese Methode synchron zum Einfügen von einer nach dem anderen statt alle gleichzeitig sperren?

Ich bin in der Lage, das Problem mit diesem Test-Controller zu reproduzieren:

[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: Dieser Code funktioniert wie ein Zauber dank Peter Antwort. Kein Stillstand. Leistung war gut und keine Langsamkeit bemerkt.

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

Warum verwenden Sie 'ConfigureAwait (false)' nicht, wenn Sie auf die Aufgabe warten? –

+2

@PeterBruins was hat 'ConfigureAwait' damit zu tun? Op spricht auch über Deadlock in SQL Server nicht in .NET-Code. Und auch 'ConfigureAwait' ist keine Lösung für alle Probleme. –

+0

Sie meinen, warten db.SaveChangesAsync(). ConfigureAwait (false)? Ich werde es versuchen und Sie wissen lassen. – expirat001

Antwort

1

Sie könnten SemaphoreSlim verwenden, um den Zugriff auf die Datenbank zu beschränken. Dieser Semaphore kann asynchron erwartet werden.

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

Danke Peter. Wäre es möglich, mir zu sagen, wie man SemaphoreSlim in meinem Code implementiert? – expirat001

+0

Ich versuche es jetzt und ich werde mit den Ergebnissen aktualisieren. – expirat001

+0

Es funktionierte wie ein Charme, 20 000 Posts und 20 000 Einträge in der DB. – expirat001