कॉल करता है मैं बैच प्रसंस्करण प्रणाली का निर्माण कर रहा हूं। Units
के बैच 20-1000 से मात्रा में आते हैं। प्रत्येक Unit
अनिवार्य रूप से मॉडल का एक पदानुक्रम (एक मुख्य मॉडल और कई बाल मॉडल) है। मेरे कार्य में प्रत्येक मॉडल पदानुक्रम को एक लेनदेन के रूप में डेटाबेस में सहेजना शामिल है (या तो प्रत्येक पदानुक्रम करता है या यह वापस रोल करता है)। दुर्भाग्यवश EF
हजारों रिकॉर्ड रखने की उनकी क्षमता के कारण मॉडल पदानुक्रम के दो हिस्सों को संभालने में असमर्थ था।ईएफ प्रतिस्पर्धा SaveChanges()
मैंने इसे हल करने के लिए क्या किया है, इन दो संभावित उच्च गिनती मॉडल को संभालने के लिए SqlBulkCopy
स्थापित किया गया है और EF
शेष आवेषण (और संदर्भित अखंडता) को संभालने दें।
बैच लूप:
foreach (var unitDetails in BatchUnits)
{
var unitOfWork = new Unit(unitDetails);
Task.Factory.StartNew(() =>
{
unitOfWork.ProcessX(); // data preparation
unitOfWork.ProcessY(); // data preparation
unitOfWork.PersistCase();
});
}
इकाई:
class Unit
{
public PersistCase()
{
using (var dbContext = new CustomDbContext())
{
// Need an explicit transaction so that
// EF + SqlBulkCopy act as a single block
using (var scope = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions() {
IsolationLevel = System.Transaction.IsolationLevel.ReadCommitted
}))
{
// Let EF Insert most of the records
// Note Insert is all it is doing, no update or delete
dbContext.Units.Add(thisUnit);
dbContext.SaveChanges(); // deadlocks, DbConcurrencyExceptions here
// Copy Auto Inc Generated Id (set by EF) to DataTables
// for referential integrity of SqlBulkCopy inserts
CopyGeneratedId(thisUnit.AutoIncrementedId, dataTables);
// Execute SqlBulkCopy for potentially numerous model #1
SqlBulkCopy bulkCopy1 = new SqlBulkCopy(...);
...
bulkCopy1.WriteToServer(dataTables["#1"]);
// Execute SqlBulkCopy for potentially number model #2
SqlBulkCopy bulkCopy2 = new SqlBulkCopy(...);
...
bulkCopy2.WriteToServer(dataTables["#2"]);
// Commit transaction
scope.Complete();
}
}
}
}
अभी मैं अनिवार्य रूप से एक रॉक और एक मुश्किल जगह के बीच फंस कर रहा हूँ। अगर मैं IsolationLevel
को ReadCommitted
पर सेट करता हूं, तो मुझे विभिन्न Tasks
में EF
INSERT
कथन के बीच deadlocks मिलते हैं।
IsolationLevel
ReadUncommitted
(जो मैं ठीक हो जाएगा सोचा था कि जब से मैं किसी भी SELECTs
नहीं कर रहा हूँ) मैं DbConcurrencyExceptions
मिलता है मैं निर्धारित किया है।
मैं DbConcurrencyExceptions
और Entity Framework
के बारे में कोई अच्छा जानकारी प्राप्त करने में असमर्थ रहा हूँ, लेकिन मुझे लगता है कि ReadUncommitted
अनिवार्य रूप से EF
जानकारी अमान्य "डाला पंक्तियों" प्राप्त करने के लिए खड़ी कर रहा है अनुमान लगा रहा हूँ।
अद्यतन
यहाँ क्या वास्तव में मेरे मुद्दों deadlocking जबकि आवेषण कर खड़ी कर रहा है पर कुछ पृष्ठभूमि जानकारी है:
जाहिर है यह एक ही मुद्दा कुछ साल पहले मौजूद था जब Linq करने के लिए एसक्यूएल बाहर आया और माइक्रोसॉफ्ट ने यह तय करके इसे ठीक किया कि scope_identity() कैसे चुना जाता है। यह सुनिश्चित नहीं है कि एक ही समस्या इकाई फ्रेमवर्क के साथ आने पर SQL स्थिति समस्या होने पर उनकी स्थिति क्यों बदल गई है।
_competing_ या _completing_? –