Wir machen erhebliche Verwendung von Entity Framework in einer Datenbank erstes Modell mit Entity Framework 6 und SqlSever 2012.Entity Framework Deadlocks und Concurrency
Wir haben eine Reihe von ziemlich langen laufenden Prozesse (10 von Sekunden), die jeweils eine erstellen Objekt des gleichen Typs mit unterschiedlichen Daten Diese Objekte schreiben und löschen Daten in der Datenbank unter Verwendung des Entity-Frameworks. So weit, ist es gut. Um die Leistung der Anwendung zu verbessern, wir suchen läuft diese Operationen parallel und als solche das Task
Konstrukt verwenden, dies zu achive wie folgt:
Private Async Function LongRunningProcessAsync(data As SomeData) As Task(Of LongRunningProcessResult)
Return Await Task.Factory.StartNew(Of LongRunningProcessResult)(Function()
Return Processor.DoWork(data)
End Function)
End Function
wir laufen 10 davon und auf sie warten alle auf Ergänzen mit Task.WaitAll
Class Processor
Public Function DoWork(data As SomeData) As LongRunningProcessResult
Using context as new dbContext()
' lots of database calls
context.saveChanges()
end Using
' call to sub which creates a new db context and does some stuff
doOtherWork()
' final call to delete temporary database data
using yetAnotherContext as new dbContext()
Dim entity = yetAnotherContext.temporaryData.single(Function(t) t.id = me.Id)
yetAnotherContext.temporaryDataA.removeAll(entity.temporaryDataA)
yetAnotherContext.temporaryDataB.removeAll(entity.temporaryDataB)
yetAnotherContext.temporaryData.remove(entity)
' dbUpdateExecption Thrown here
yetAnotherContext.SaveChanges()
end using
End Function
End Class
dieses gut ~ 90% der Zeit arbeitet die anderen 10% ist damit der Datenbankserver mit einem inneren deadlocking Ausnahme
alle Prozessoren verwenden die gleichen Tabellen Deadlocks aber teilen Sie absolut keine Daten zwischen Prozessen (und hängen nicht von denselben FK-Zeilen ab) und erstellen Sie alle ihre eigenen Entityframework-Kontexte ohne gemeinsame Interaktion zwischen ihnen.
Überprüfung Profilierungsverhalten der Sql Server
Instanz sehen wir eine große Anzahl von sehr kurzlebigen Sperren Akquisitionen und Releases zwischen jeder erfolgreichen Abfrage. Was zu einer eventuellen Deadlockkette bis:
Lock:Deadlock Chain Deadlock Chain SPID = 80 (e413fffd02c3)
Lock:Deadlock Chain Deadlock Chain SPID = 73 (e413fffd02c3)
Lock:Deadlock Chain Deadlock Chain SPID = 60 (6cb508d3484c)
die Schlösser selbst von KEY
Typ sind und die deadlocking Abfragen sind alle für den gleichen Tisch, aber mit verschiedenen Schlüsseln der Form:
exec sp_executesql N'DELETE [dbo].[temporaryData]
WHERE ([Id] = @0)',N'@0 int',@0=123
Wir relativ neu zum Entity-Framework und sind nicht in der Lage, die Ursache von scheinbar überspannten Sperren zu identifizieren (ich kann über sql profiler nicht feststellen, welche Zeilen gerade gesperrt sind).
EDIT: deadlock.xdl
EDIT2: Aufruf saveChanges
nach jedem Entfernen Anweisung, den Stillstand noch entfernt nicht ganz verstehen, warum es
Haben Sie eine xdl-Datei verfügbar? Ist dies der Fall, überprüfen Sie die Transaktionsisolationsstufe für jeden der beteiligten Prozesse. Ich würde Dollars auf Donuts wetten, dass mindestens einer von ihnen auf "serialisierbar" eingestellt ist. –
isolationlevel = "lesen Sie committed (2)" für alle – user2732663
Sieht so aus, als hätte ich diese Wette verloren. :) Können Sie die XDL-Datei irgendwo zur Analyse bringen? –