के कारण मेरे आवेदन में एमएसडीटीसी वृद्धि से बचने की कोशिश कर रहा हूं। मैं LINQ का उपयोग SQL सर्वर एक्सप्रेस 2008 R2 के साथ कर रहा हूं, और बाद में पूर्ण संस्करण का उपयोग कर रहा हूं।नेस्टेड ट्रांजैक्शनस्कोप और/या नेस्टेड कनेक्शन एमएसडीटीसी एस्केलेशन
मैंने डेटाबेस रैपर वर्ग लिखा है जो आवश्यकतानुसार कनेक्शन बनाता है और जितनी जल्दी हो सके उनका निपटान करता है। कनेक्शन स्ट्रिंग सभी कनेक्शनों में समान है।
public class SqlServerDatabaseWrapper {
public SqlServerDatabaseWrapper(string connectionString) {
ConnectionString = connectionString;
}
public string ConnectionString { get; private set; }
private static IDbConnection GetOpenConnection() {
var conn = new SqlConnection(ConnectionString);
conn.Open();
return conn;
}
// there is also a second method to return a value
// there is PerformCommandAction for SqlCommand as well
public void PerformDataContextAction<TContext>(Func<IDbConnection, TContext> creator, Action<TContext> action) where TContext : DataContext {
PerformConnectionAction(conn => {
using (var context = creator(conn))
action(context);
});
}
// there is also a second method to return a value
public void PerformConnectionAction(Action<IDbConnection> action) {
using (IDbConnection conn = GetOpenConnection(ConnectionString)) {
action(conn);
}
}
}
प्रयुक्त इस प्रकार है::
var db = new SqlServerDatabaseWrapper(connectionString);
db.PerformDataContextAction(
conn => new SomeDataContext(conn),
context => { /* do something */ }
);
अगर मैं PerformConnectionAction विधि की सामग्री के चारों ओर एक ताला लगाना केवल एक ही है, इसलिए
यहाँ मेरी कक्षा की एक बहुत ही slimmed नीचे संस्करण है एक समय में चला सकते हैं, तो सब कुछ काम करता है लेकिन एक उल्लेखनीय प्रदर्शन जुर्माना है। हालांकि, जब मैं इसे हटा देता हूं, तो यह बढ़ता है।
कोड है कि आवरण उपयोग कर रहा है एक TransactionScope उपयोग कर रहा है, और वहाँ TransactionScopes का घोंसला बनाने से किया जा सकता है और/या कॉल करने के लिए या तो PerformDataContextAction या PerformConnectionAction (जो एक ही कनेक्शन स्ट्रिंग के साथ एक नया कनेक्शन बनाने के); छद्म कोड में (के रूप में इस विभिन्न वर्गों/तरीकों के पार हो सकता है):
var db = new SqlServerDatabaseWrapper(connectionString)
using (TransactionScope tran = new TransactionScope()) {
db.PerformDataContextAction(
/* ... */,
context => {
using (TransactionScope tran2 = new TransactionScope()) {
db.PerformConnectionAction(conn => { /* some stuff */ });
tran2.Complete();
}
}
tran.Complete();
}
यह भी ध्यान रखें स्थिर सदस्यता तरीकों जो विभिन्न बिंदुओं पर हो सकता है के उपयोग करता है।
मैं भी जोड़ना चाहिए कि कनेक्शन स्ट्रिंग इस प्रकार है:
Data Source=.\SQLEXPRESS;Initial Catalog=db1;User Id=test1;Password=test1;MultipleActiveResultSets=true;Enlist=false;
सवाल यह है कि, मैं कैसे refactor है/मेरे कोड को फिर से लिखने ताकि अपने आवेदन MSDTC बिना, अच्छी तरह से प्रदर्शन कर सकते हैं, और शुरू करने ताले बिना ?
धन्यवाद
SQL सर्वर का कौन सा संस्करण आप उपयोग कर रहे हैं? – Oded
एसक्यूएल एक्सप्रेस 2008 आर 2, बाद में पूर्ण संस्करण – enashnash
पर रखा जाना चाहिए, मैं थोड़ा उलझन में हूं कि लॉक जोड़ने से वृद्धि बढ़ जाती है, क्योंकि 'ट्रांज़ेक्शनस्कोप थ्रेड-बाउंड हैं, और ताले केवल थ्रेड के इंटरप्ले को प्रभावित करते हैं, लेकिन ऑर्डर नहीं एक थ्रेड के अंदर संचालन के, जब तक कि आपका थ्रेडिंग गैर-निर्धारक व्यवहार प्रस्तुत न करे, जिसमें मैं देख सकता हूं कि ताले कैसे चीजें बदलते हैं। यदि आप अभी भी किसी उत्तर में रुचि रखते हैं, तो कृपया हमें थ्रेड-वार पर क्या चल रहा है इसके बारे में और जानें। –