Noi fare uso considerevole di Entity Framework in un primo modello di database con Entity Framework 6 e SqlSever 2012.Entity Framework deadlock e Concurrency
Abbiamo un certo numero di processi in esecuzione piuttosto lunghi (10 di secondi), che ciascun creare un oggetto dello stesso tipo con dati diversi questi oggetti nella loro creazione scrivono e cancellano i dati nel database usando il framework di entità. Fin qui tutto bene. Al fine di migliorare le prestazioni dell'applicazione stiamo cercando di corre queste operazioni in parallelo e in quanto tali stanno usando il Task
costrutto per raggiungere questo obiettivo nel modo seguente:
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
corriamo 10 di questi e attendere per tutti loro a completare con 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
questo funziona bene ~ 90% del tempo il restante 10% è deadlock il server di database con un'eccezione deadlocking interna
tutti i processori utilizzano le stesse tabelle, ma non condividere assolutamente dati tra processi (e non dipendono dalle stesse righe FK) e creare tutti i propri contesti di entità esterna senza interazione condivisa tra loro.
esaminando il comportamento di creazione profili dell'istanza Sql Server
, vediamo un gran numero di acquisizioni e rilasci di blocchi di durata molto breve tra ogni query completata. Che porta a una eventuale catena deadlock:
Lock:Deadlock Chain Deadlock Chain SPID = 80 (e413fffd02c3)
Lock:Deadlock Chain Deadlock Chain SPID = 73 (e413fffd02c3)
Lock:Deadlock Chain Deadlock Chain SPID = 60 (6cb508d3484c)
Le serrature stessi sono di tipo KEY
e le query blocco critico sono tutti per la stessa tabella ma con diverse chiavi della forma:
exec sp_executesql N'DELETE [dbo].[temporaryData]
WHERE ([Id] = @0)',N'@0 int',@0=123
Noi relativamente nuova al framework di entità e non riescono a identificare la causa principale di ciò che appare nei blocchi sovrascritti (non sono in grado di identificare tramite sql profiler le righe esatte bloccate).
EDIT: deadlock.xdl
EDIT2: Calling saveChanges
dopo ogni istruzione remove toglie la situazione di stallo ancora non capisco il motivo per cui è stato deadlocking
Hai un file xdl disponibile? In tal caso, controllare il livello di isolamento della transazione per ciascuno dei processi coinvolti. Scommetterei dollari a ciambelle che almeno uno di loro è impostato su "serializzabile". –
isolationlevel = "read committed (2)" per tutti – user2732663
Sembra che abbia perso la scommessa. :) Sei in grado di mettere il file XDL da qualche parte per l'analisi? –