我們做數據庫中的第一款車型大量使用實體框架的實體框架6和SQLSEVER 2012實體框架死鎖和併發
我們擁有一批相當長時間運行的進程(秒10的),每個創建的這些對象在創建時使用實體框架在數據庫中寫入和刪除數據。到現在爲止還挺好。爲了提高我們正在尋找應用程序的性能在並行運行這些操作,因此使用Task
結構來實現這一目標如下:
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
我們運行的這10個,並等待他們全部完成使用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
這個效果很好〜90%的時間,其他10%是鎖死與內部死鎖例外數據庫服務器
所有處理器使用相同的表,但在進程之間絕對不共享數據(並且不依賴於相同的FK行),並且在它們之間沒有共享交互的情況下創建所有自己的實體框架上下文。
查看Sql Server
實例的性能分析行爲,我們看到每個成功查詢之間存在大量非常短暫的鎖定獲取和釋放。領導到一個最終的僵局鏈:
Lock:Deadlock Chain Deadlock Chain SPID = 80 (e413fffd02c3)
Lock:Deadlock Chain Deadlock Chain SPID = 73 (e413fffd02c3)
Lock:Deadlock Chain Deadlock Chain SPID = 60 (6cb508d3484c)
的鎖本身KEY
型和死鎖的查詢都是爲了同一個表,但與形式的不同的密鑰:
exec sp_executesql N'DELETE [dbo].[temporaryData]
WHERE ([Id] = @0)',N'@0 int',@0=123
我們比較新到實體框架,並且無法識別出現超大範圍鎖定的根本原因(我無法通過sql分析器確定確切的行被鎖定)。
編輯:deadlock.xdl
EDIT2:調用saveChanges
每個刪除語句刪除死鎖後,仍然不明白爲什麼它被鎖死
您是否有可用的xdl文件?如果是這樣,請檢查涉及的每個流程的事務隔離級別。我會打賭美元甜甜圈,至少其中一個被設置爲「可序列化」。 –
isolationlevel =「閱讀承諾(2)」爲所有 – user2732663
看起來我失去了那個賭注。 :)你可以把XDL文件放在某個地方進行分析嗎? –