दोष-सहिष्णुता, स्किप और पुनःप्रयास नीतियाँ
क्षणिक डेटा त्रुटियों के प्रति जॉब को सुदृढ़ बनाने के लिए स्किप, पुनःप्रयास और पुनःआरंभ अर्थविज्ञान कॉन्फ़िगर कीजिए।
दोष-सहिष्णुता, स्किप और पुनःप्रयास नीतियाँ, CoddyKit पर Spring Boot 4 की संपूर्ण मार्गदर्शिका का एक निःशुल्क पाठ है। यह 4 में से 3वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह Spring Boot 4 की संपूर्ण मार्गदर्शिका सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। Spring Boot 4 की संपूर्ण मार्गदर्शिका पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
दोष-सहनशीलता क्यों महत्वपूर्ण है
बैच Job बहुत बड़ी मात्रा में डेटा संसाधित करती हैं और वास्तविक दुनिया का डेटा अव्यवस्थित होता है। एक गलत प्रारूप वाली पंक्ति, क्षणिक डेटाबेस डेडलॉक या अस्थिर डाउनस्ट्रीम कॉल ऐसी Job को विफल कर सकती है, जो पहले ही लाखों रिकॉर्ड संसाधित कर चुकी हो।
Spring Batch chunk-आधारित स्टेप को दोष-सहनशीलता देता है, ताकि वह पूरी रन को रद्द किए बिना इन समस्याओं से बच सके। इसके तीन मुख्य साधन हैं:
- Skip — ऐसी त्रुटियाँ पैदा करने वाले रिकॉर्ड हटा दें जिनसे उबरना संभव नहीं है (जैसे खराब डेटा) और आगे बढ़ते रहें।
- Retry — क्षणिक त्रुटि के कारण विफल हुए ऑपरेशन पर फिर प्रयास करें (जैसे लॉक का समय समाप्त होना)।
- Restart — विफल Job इंस्टेंस को शुरुआत से चलाने के बजाय जहाँ रुका था वहीं से फिर शुरू करें।
इनका साथ में उपयोग करने पर नाज़ुक Job भरोसेमंद बन जाती है।
किसी Step पर दोष-सहनशीलता सक्षम करना
दोष-सहनशीलता वैकल्पिक रूप से सक्षम की जाती है। Chunk स्टेप बनाते समय स्टेप बिल्डर पर .faultTolerant() कॉल करके दोष-सहनशील रूप पर स्विच करें। इसके बाद ही आप skip और retry नियम घोषित कर सकते हैं।
.faultTolerant() के बिना रीडर, प्रोसेसर या राइटर द्वारा उत्पन्न कोई भी अपवाद chunk को रोलबैक कर देता है और स्टेप तुरंत विफल हो जाता है।
@Bean
public Step importStep(JobRepository jobRepository,
PlatformTransactionManager txManager,
ItemReader<Customer> reader,
ItemProcessor<Customer, Customer> processor,
ItemWriter<Customer> writer) {
return new StepBuilder("importStep", jobRepository)
.<Customer, Customer>chunk(100, txManager)
.reader(reader)
.processor(processor)
.writer(writer)
.faultTolerant() // unlocks skip & retry configuration
.build();
}Skip नीतियाँ कॉन्फ़िगर करना
Skip करने से स्टेप ऐसे व्यक्तिगत आइटम को हटा सकता है जो कभी सफल नहीं हो सकता — आम तौर पर पार्सिंग या सत्यापन विफलता — और अगले आइटम के साथ आगे बढ़ सकता है।
आप घोषित करते हैं कि कौन-से अपवाद skip किए जा सकते हैं और एक वैश्विक सीमा निर्धारित करते हैं:
.skip(Exception.class)— किसी अपवाद प्रकार को skip किए जा सकने योग्य चिह्नित करता है।.noSkip(Exception.class)— किसी उपप्रकार को skip किए जाने से स्पष्ट रूप से बाहर रखता है।.skipLimit(n)— स्टेप विफल होने से पहले अनुमत skips की कुल संख्या।
जब संचयी skip गणना skipLimit से अधिक हो जाती है, तो स्टेप रद्द हो जाता है। इससे किसी Job को हज़ारों खराब रिकॉर्ड चुपचाप निगलने से रोका जाता है।
return new StepBuilder("importStep", jobRepository)
.<Customer, Customer>chunk(100, txManager)
.reader(reader)
.processor(processor)
.writer(writer)
.faultTolerant()
.skip(FlatFileParseException.class) // bad CSV line
.skip(ValidationException.class) // failed bean validation
.noSkip(FileNotFoundException.class) // never skip this
.skipLimit(50) // fail after 50 skips
.build();Skip का Chunks के साथ संबंध
Skip का व्यवहार इस बात पर निर्भर करता है कि अपवाद कहाँ उत्पन्न होता है:
- रीडर skip: खराब आइटम हटा दिया जाता है और पढ़ना जारी रहता है — सस्ता, बिना रोलबैक के।
- प्रोसेसर skip: chunk लेन-देन रोलबैक होता है, फिर Spring Batch chunk को आइटम-दर-आइटम दोबारा संसाधित करता है और केवल समस्या पैदा करने वाले आइटम को skip करता है।
- राइटर skip: वही स्कैन और फिर प्रयास — chunk रोलबैक होता है और आइटम एक-एक करके फिर लिखे जाते हैं, ताकि अकेले खराब आइटम को अलग करके skip किया जा सके।
क्योंकि प्रोसेसर/राइटर skips से रोलबैक और एकल-आइटम का पुनः निष्पादन होता है, वे रीडर skips से बहुत अधिक महँगे होते हैं। जहाँ संभव हो, सत्यापन रीडर/प्रोसेसर में रखें, ताकि विफलताएँ जल्दी पकड़ में आ जाएँ।
एक कस्टम SkipPolicy
घोषणात्मक .skip()/.skipLimit() API अधिकांश मामलों को संभालती है, लेकिन पूरी तरह कस्टम तर्क के लिए आप SkipPolicy लागू कर सकते हैं — उदाहरण के लिए, एक अपवाद प्रकार के लिए दूसरे की तुलना में अधिक skips की अनुमति देना या अपवाद संदेश की जाँच करना।
shouldSkip विधि उत्पन्न Throwable और वर्तमान skip गणना प्राप्त करती है; skip करने के लिए true लौटाएँ, या स्टेप विफल करने के लिए SkipLimitExceededException उत्पन्न करें।
public class CustomSkipPolicy implements SkipPolicy {
@Override
public boolean shouldSkip(Throwable t, long skipCount)
throws SkipLimitExceededException {
if (t instanceof FileNotFoundException) {
return false; // fatal: never skip
}
if (t instanceof ValidationException && skipCount < 100) {
return true; // tolerate up to 100 bad records
}
if (t instanceof FlatFileParseException && skipCount < 20) {
return true;
}
return false;
}
}Retry कब करें और Skip कब
Skip और retry के बीच निर्णय त्रुटि की प्रकृति पर निर्भर करता है:
- Retry: ऐसी क्षणिक त्रुटि पर फिर प्रयास करें जो दोबारा प्रयास करने पर सफल हो सकती है: डेडलॉक का शिकार, लॉक का समय समाप्त होना, आशावादी लॉकिंग का टकराव, नेटवर्क की अल्पकालिक समस्या।
- Skip: ऐसी नियतात्मक त्रुटि को छोड़ दें जो हमेशा विफल होगी: गलत प्रारूप वाला इनपुट, विफल व्यावसायिक सत्यापन, डेटा द्वारा स्वयं उल्लंघन की गई बाधा।
नियतात्मक त्रुटि पर retry करने से विफल होने से पहले केवल प्रयास व्यर्थ होते हैं; क्षणिक त्रुटि को skip करने से वह डेटा हट जाता है जो सफल हो सकता था। अपने अपवादों का सही वर्गीकरण करें — यही इस पाठ का मुख्य डिज़ाइन निर्णय है।
Retry नीतियाँ कॉन्फ़िगर करना
पुनःप्रयास विफल हो रहे कार्य को छोड़ने से पहले, कॉन्फ़िगर की गई संख्या तक फिर से चलाता है। दोष-सहिष्णु चरण पर आप यह घोषित करते हैं:
.retry(Exception.class)— वे अपवाद प्रकार जिन पर पुनःप्रयास किया जा सकता है।.noRetry(Exception.class)— किसी उपप्रकार को बाहर रखने के लिए।.retryLimit(n)— प्रत्येक आइटम के लिए अधिकतम प्रयास (पहला प्रयास भी इसमें शामिल है)।
जब कोई आइटम पुनःप्रयास योग्य अपवाद के साथ विफल होता है, तो खंड का लेन-देन वापस कर दिया जाता है और आइटम को retryLimit बार तक फिर से चलाया जाता है। यदि वह फिर भी विफल रहता है, तो अपवाद आगे भेज दिया जाता है — उस स्थिति में उसे छोड़ा जा सकता है, यदि उसे छोड़ने योग्य भी घोषित किया गया हो।
return new StepBuilder("importStep", jobRepository)
.<Customer, Customer>chunk(100, txManager)
.reader(reader)
.processor(processor)
.writer(writer)
.faultTolerant()
.retry(DeadlockLoserDataAccessException.class)
.retry(OptimisticLockingFailureException.class)
.retryLimit(3) // up to 3 attempts per item
.skip(ValidationException.class)
.skipLimit(50)
.build();पुनःप्रयासों के बीच विराम
तुरंत पुनःप्रयास करके किसी प्रतिस्पर्धित संसाधन पर लगातार अनुरोध भेजने से अक्सर प्रतिस्पर्धा और बढ़ जाती है। एक विराम नीति प्रयासों के बीच विलंब जोड़ती है। ExponentialBackOffPolicy प्रतीक्षा अवधि को गुणात्मक रूप से बढ़ाती है, जिससे भार धीरे-धीरे फैलता है।
आप .retryPolicy(...) के माध्यम से या RetryTemplate को कॉन्फ़िगर करके अपनी कस्टम RetryPolicy या BackOffPolicy जोड़ते हैं। नीचे प्रतीक्षा 200ms से शुरू होती है और प्रत्येक प्रयास पर दोगुनी होकर अधिकतम 5s तक पहुँचती है।
@Bean
public RetryTemplate retryTemplate() {
ExponentialBackOffPolicy backOff = new ExponentialBackOffPolicy();
backOff.setInitialInterval(200); // 200 ms
backOff.setMultiplier(2.0); // 200, 400, 800, ...
backOff.setMaxInterval(5000); // cap at 5 s
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3,
Map.of(DeadlockLoserDataAccessException.class, true));
RetryTemplate template = new RetryTemplate();
template.setBackOffPolicy(backOff);
template.setRetryPolicy(retryPolicy);
return template;
}श्रोता: छोड़े गए आइटम और पुनःप्रयास देखना
रिकॉर्ड को चुपचाप छोड़ देना जोखिमपूर्ण है — आपको ऑडिट-ट्रेल की आवश्यकता होती है। SkipListener कॉलबैक प्रत्येक छोड़े गए आइटम के लिए चलते हैं, ताकि आप उसका लॉग बना सकें, उसे डेड-लेटर तालिका में लिख सकें या चेतावनी भेज सकें।
onSkipInRead— पढ़ने की विफलता को छोड़ दिया गया।onSkipInProcess— आपको आइटम और अपवाद दोनों देता है।onSkipInWrite— वह आइटम जिसे लिखा नहीं जा सका।
इसे चरण बिल्डर पर .listener(skipListener) के साथ पंजीकृत करें। पुनःप्रयास के प्रयासों को देखने के लिए RetryListener भी उपलब्ध है।
public class LoggingSkipListener implements SkipListener<Customer, Customer> {
private static final Logger log =
LoggerFactory.getLogger(LoggingSkipListener.class);
@Override
public void onSkipInRead(Throwable t) {
log.warn("Skipped unreadable record: {}", t.getMessage());
}
@Override
public void onSkipInProcess(Customer item, Throwable t) {
log.warn("Skipped {} in process: {}", item.getId(), t.getMessage());
}
@Override
public void onSkipInWrite(Customer item, Throwable t) {
log.warn("Skipped {} in write: {}", item.getId(), t.getMessage());
}
}पुनःआरंभ की क्षमता और कार्य रिपॉज़िटरी
छोड़ना और पुनःप्रयास किसी रन के दौरान होने वाली त्रुटियों को संभालते हैं; पुनःआरंभ उस रन को संभालता है जो पूरी तरह विफल हो गया हो। क्योंकि स्प्रिंग बैच प्रत्येक चरण का ExecutionContext और पढ़ने/लिखने की गणनाएँ कार्य रिपॉज़िटरी में सुरक्षित रखता है, उसी JobInstance को फिर से चलाने पर सब कुछ दोबारा संसाधित करने के बजाय अंतिम प्रतिबद्ध खंड से काम जारी रहता है।
मुख्य नियम:
- किसी
JobInstanceकी पहचान उसके पहचान-निर्धारक कार्य पैरामीटरों से होती है; पुनःआरंभ के लिए उन्हीं का पुनः उपयोग करें और नया इंस्टेंस शुरू करने के लिए उन्हें बदलें। - केवल गैर-
COMPLETEDस्थिति वाले कार्य (जैसेFAILED,STOPPED) ही पुनःआरंभ किए जा सकते हैं। - पुनःआरंभ पर पहले से पूर्ण चरणों को फिर से चलाने के लिए उसे
.allowStartIfComplete(true)से चिह्नित करें। .startLimit(n)से पुनःप्रयासों की सीमा तय करें, ताकि खराब चरण को अनंत बार फिर से न चलाया जाए।
सब कुछ एक साथ जोड़ना
उत्पादन-स्तर का लचीला चरण इन तीनों चिंताओं को जोड़ता है: अस्थायी विफलताओं पर विराम के साथ पुनःप्रयास करना, निश्चित रूप से खराब डेटा को सीमित संख्या के भीतर छोड़ना, हर छोड़े गए आइटम का ऑडिट करना और पुनःआरंभ के लिए कार्य रिपॉज़िटरी पर निर्भर रहना।
परतों पर ध्यान दें: विफल होने वाले आइटम पर पहले पुनःप्रयास किया जाता है; यदि वह फिर भी विफल रहता है और अपवाद छोड़ने योग्य है, तो उसे छोड़ दिया जाता है (और श्रोता उसका रिकॉर्ड रखता है)। अपवाद पुनःप्रयास योग्य और छोड़ने योग्य दोनों हो सकते हैं — पहले पुनःप्रयास समाप्त होते हैं, फिर छोड़ने का नियम लागू होता है।
return new StepBuilder("resilientImport", jobRepository)
.<Customer, Customer>chunk(100, txManager)
.reader(reader)
.processor(processor)
.writer(writer)
.faultTolerant()
// transient -> retry with backoff
.retry(DeadlockLoserDataAccessException.class)
.retryLimit(3)
// deterministic bad data -> skip
.skip(FlatFileParseException.class)
.skip(ValidationException.class)
.skipLimit(100)
// audit + restart safety
.listener(new LoggingSkipListener())
.startLimit(3)
.build();त्वरित जाँच
छोड़ने और पुनःप्रयास के अर्थ संबंधी अंतर की अपनी समझ जाँचें।
पुनरावलोकन
आपने अस्थायी और निश्चित विफलताओं के प्रति स्प्रिंग बैच चरण को लचीला बनाया:
- सहनशीलता सक्षम करें: छोड़ने या पुनःप्रयास के कोई भी नियम घोषित करने से पहले
.faultTolerant()का उपयोग करें। - छोड़ें:
.skip()+.skipLimit()से निश्चित रूप से खराब डेटा छोड़ें; प्रोसेसर या राइटर में छोड़े गए आइटम के लिए रोलबैक और एकल-आइटम को फिर से चलाना पड़ता है, इसलिए जल्दी सत्यापन करें। - पुनःप्रयास करें:
.retry()+.retryLimit()से अस्थायी त्रुटियों पर पुनःप्रयास करें और प्रतिस्पर्धा कम करने के लिए घातीय विराम जोड़ें। - सावधानी से वर्गीकृत करें: अस्थायी त्रुटियों (डेडलॉक, लॉक टाइमआउट) पर पुनःप्रयास करें और निश्चित त्रुटियों (पार्सिंग/सत्यापन) को छोड़ें। जब कोई अपवाद दोनों श्रेणियों में हो, तो पहले पुनःप्रयास और फिर छोड़ना लागू होता है।
- ऑडिट करें:
SkipListenerसे हर छोड़े गए आइटम का ऑडिट करें, ताकि कुछ भी चुपचाप गायब न हो। - पुनःआरंभ करें: विफल इंस्टेंस को अंतिम प्रतिबद्ध खंड से कार्य रिपॉज़िटरी के माध्यम से शुरू करें;
allowStartIfCompleteऔरstartLimitसे फिर से चलने की प्रक्रिया नियंत्रित करें।
एआई शिक्षक के साथ Java सीखें — निःशुल्क
अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।
- पाठ्यक्रम
- 21
- पाठ
- 84
अक्सर पूछे जाने वाले प्रश्न
क्या “दोष-सहिष्णुता, स्किप और पुनःप्रयास नीतियाँ” पाठ निःशुल्क है?
हाँ — Spring Boot 4 की संपूर्ण मार्गदर्शिका अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “दोष-सहिष्णुता, स्किप और पुनःप्रयास नीतियाँ” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। Spring Boot 4 की संपूर्ण मार्गदर्शिका पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
“दोष-सहिष्णुता, स्किप और पुनःप्रयास नीतियाँ” में मैं क्या सीखूँगा?
क्षणिक डेटा त्रुटियों के प्रति जॉब को सुदृढ़ बनाने के लिए स्किप, पुनःप्रयास और पुनःआरंभ अर्थविज्ञान कॉन्फ़िगर कीजिए। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ Spring Boot 4 की संपूर्ण मार्गदर्शिका का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।
क्या Spring Boot 4 की संपूर्ण मार्गदर्शिका शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?
पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर Spring Boot 4 की संपूर्ण मार्गदर्शिका शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 3वाँ पाठ है।
“दोष-सहिष्णुता, स्किप और पुनःप्रयास नीतियाँ” पाठ पूरा करने में कितना समय लगता है?
CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।
क्या मैं इस Spring Boot 4 की संपूर्ण मार्गदर्शिका पाठ में कोड लिख और चला सकता हूँ?
हाँ। हर Spring Boot 4 की संपूर्ण मार्गदर्शिका पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।
इस पाठ्यक्रम के सभी पाठ
- जॉब, चरण और JobRepository मॉडल
- खंड-आधारित रीडर-प्रोसेसर-राइटर प्रवाह
- दोष-सहिष्णुता, स्किप और पुनःप्रयास नीतियाँ
- विभाजन और समानांतर चरण निष्पादन