2012-04-17 8 views
6

मेरे पास Azure में चल रहे LINQ-TO-SQL का उपयोग करके काफी बड़ा वेब एप्लिकेशन है, और मुझे SQL-Azure से क्षणिक त्रुटियों का सामना करना पड़ रहा है और इसलिए रीट्रीज़ को लागू करने की आवश्यकता है। मैं Transient Fault Handling Framework और कई साइटों है कि यह कैसे उपयोग करने के लिए उदाहरण देने के बारे में पता है, लेकिन लगता है कि यह करने के लिए कुछ इसी तरह अपनी LINQ प्रश्नों में से हर एक रैप करने के लिए है यह लग रहा है:SQL Azure पर LINQ-TO-SQL के लिए पुन: प्रयास करें - कुशल कार्यान्वयन?

RetryPolicy retry = new RetryPolicy<MyRetryStrategy>(5, TimeSpan.FromSeconds(5)); 
Result = retry.ExecuteAction(() => 
{ 
    … LINQ query here... 
}); 

LINQ प्रश्नों के सैकड़ों के साथ मेरी डेटा परत में, यह वास्तव में गन्दा लगता है, साथ ही तथ्य यह है कि कई बार क्वेरी वास्तव में तब तक निष्पादित नहीं की जाती जब तक परिणाम न हों। उदाहरण के लिए, मेरी डेटा परत में मेरे अधिकांश फ़ंक्शन एक IQueryable <> व्यापार परत तक वापस लौटाते हैं, (जो उन्हें सूची लौटने से अधिक लचीला बनाता है)। तो इसका मतलब यह होगा कि आपको डेटाबेस रीट्री लॉजिक के साथ अपनी व्यावसायिक तर्क परत को कूड़े रखना होगा - बदसूरत।

इसलिए मैं आदेश डेटा स्तर में पुन: प्रयास करें तर्क रखने के लिए लगता है, मैं .ToList डाल करने के लिए() मेरे सभी प्रश्नों तो वे ऊपर परत में वहीं क्रियान्वित कर रहे हैं, न कि के लिए होगा।

मैं वास्तव में चाहता हूं कि कुछ बेस क्लास में पुनः प्रयास तर्क लागू करने का कोई तरीका था और मेरे सभी प्रश्नों को बदलने की ज़रूरत नहीं है। ऐसा लगता है कि ईएफ को भी यह समस्या होगी।

ऑटो-रीट्रीज़ करने के लिए एसक्यूएल-एज़ूर टीम को आजमाने और बात करने का असली जवाब है, इसलिए हमें इसके बारे में चिंता करने की ज़रूरत नहीं है?

उत्तर

0

मुझे एक अच्छा समाधान पता नहीं है, क्योंकि LINQ से SQL हमें क्वेरी को अवरुद्ध करने की अनुमति नहीं देता है। लेकिन थोड़ा कोड रिफैक्टर मदद कर सकता है। (छद्म कोड) की तरह कुछ:

public Result QueryWithRetry(IQueryable query) 
{ 
     RetryPolicy retry = new RetryPolicy<MyRetryStrategy>(5, TimeSpan.FromSeconds(5)); 
    (() => 
    { 
     return retry.ExecuteAction(query); 
    } 
} 

अब यह इस पद्धति का आह्वान करने के लिए थोड़ा आसान है: (यहाँ ... LINQ क्वेरी ...)

परिणाम = QueryWithRetry;

हालांकि, अभी भी आपके कोड को संशोधित करने और प्रत्येक क्वेरी को बदलने की आवश्यकता है।

सर्वश्रेष्ठ सादर,

मिंग जू।

+0

इससे थोड़ा सा मदद मिलती है, लेकिन क्या मुझे अभी भी उन प्रश्नों के बारे में चिंता करने की ज़रूरत नहीं है जो वास्तव में कोड में बाद में निष्पादित नहीं होते हैं, जहां उन्हें गणना की जाती है? इसलिए मुझे वास्तव में प्रत्येक क्वेरी की जांच करनी होगी और यह पता लगाना होगा कि डेटाबेस कहां कहलाता है। – PeteShack

+0

क्षमा करें, मैं आपको बहुत अच्छी तरह से समझ नहीं सकता। क्या आपका मतलब है कि अगर कुछ गलत हो जाता है तो आप चिंतित हैं, इस मुद्दे के स्रोत को ढूंढना अधिक कठिन होगा क्योंकि क्वेरी को एक रेट्री फ्रेमवर्क के अंदर लपेटा गया है? इस मामले में, मैं आपको पुनः प्रयास करने के लिए ब्रेक पॉइंट सेट करने का सुझाव देना चाहता हूं। निष्पादन क्रिया, और कोड के माध्यम से कदम। –

+0

नहीं, मेरा मतलब है कि एक मौजूदा ऐप में पुनः प्रयास तर्क जोड़ना सैकड़ों प्रश्नों के साथ एक कठिन कार्य होगा - मुख्य रूप से क्योंकि डेटाबेस कॉल डेटा परत में linq-to-sql क्वेरी में आवश्यक नहीं है। क्वेरी का निष्पादन तब तक देरी हो सकती है जब तक IQueryable वास्तव में गणना नहीं की जाती - जो व्यापार परत में हो सकती है। इस समस्या के लिए बस एक साफ समाधान प्रतीत नहीं होता है। – PeteShack

1

इस तरह कुछ लागू करने की आवश्यकता के बाद, मैं आगे बढ़ गया और इसे एक पुस्तकालय बना दिया: https://github.com/daveaglick/LinqToSqlRetry (एमआईटी लाइसेंस प्राप्त और NuGet पर उपलब्ध)।

इसके बजाय आप SubmitChangesRetry() लिख कर SubmitChanges() कॉल पुन: प्रयास कर सकते हैं:

using(var context = new MyDbContext()) 
{ 
    context.Items.InsertOnSubmit(new Item { Name = "ABC" }); 
    context.SubmitChangesRetry(); 
} 

तुम भी Retry() विस्तार विधि का उपयोग कर प्रश्नों पुन: प्रयास कर सकते हैं:

using(var context = new MyDbContext()) 
{ 
    int count = context.Items.Where(x => x.Name == "ABC").Retry().Count(); 
} 

विशिष्ट पुन: प्रयास करें तर्क नीतियों से चलाया है।

int retryCount = 0; 
while (true) 
{ 
    try 
    { 
     return func(); 
    } 
    catch (Exception ex) 
    { 
     TimeSpan? interval = retryPolicy.ShouldRetry(retryCount, ex); 
     if (!interval.HasValue) 
     { 
      throw; 
     } 
     Thread.Sleep(interval.Value); 
    } 
    retryCount++; 
} 

समझ लें कि func() करने के लिए कॉल और retryPolicy वस्तु में समारोह उपयोग के आधार पर प्रदान की जाती हैं: हुड के अंतर्गत, पुन: प्रयास तंत्र की तरह दिखता है। यह सिर्फ आपको एक विचार देता है कि पुनः प्रयास लूप के दौरान क्या हो रहा है। अधिक जानकारी के लिए बस भंडार में देखें।

संबंधित मुद्दे