मुझे वही समस्या थी। मैं स्प्रिंग कैशिंग एनोटेशन के माध्यम से कैश स्टोर के रूप में रेडिस का उपयोग करके डेटाबेस के खिलाफ कुछ डेटा सेवाएं विकसित कर रहा हूं। यदि रेडिस सर्वर अनुपलब्ध हो जाता है, तो मैं चाहता हूं कि सेवाएं अपवादों को फेंकने के बजाय बिना कैश किए काम करना जारी रखें।
सबसे पहले मैंने एक कस्टम CacheErrorHandler की कोशिश की, जो स्प्रिंग द्वारा प्रदान किया गया एक तंत्र है। यह काफी काम नहीं आया, क्योंकि यह केवल रनटाइम अपवादों को संभालता है, और अभी भी java.net.ConnectException जैसी चीजों को उड़ा देता है।
अंत में मैंने जो किया वह RedisTemplate का विस्तार करता है, कुछ निष्पादन() विधियों को ओवरराइड करता है ताकि वे अपवादों को प्रचारित करने के बजाय चेतावनियां लॉग कर सकें। यह एक हैक की तरह लगता है, और मैंने बहुत कम निष्पादन() विधियों या बहुत से ओवरराइड किए होंगे, लेकिन यह मेरे सभी परीक्षण मामलों में एक आकर्षण की तरह काम करता है।
हालाँकि, इस दृष्टिकोण का एक महत्वपूर्ण परिचालन पहलू है। यदि रेडिस सर्वर अनुपलब्ध हो जाता है, तो आपको इसे फिर से उपलब्ध कराने से पहले इसे फ्लश करना होगा (प्रविष्टियों को साफ करना)। अन्यथा इस बात की संभावना है कि इस दौरान हुए अपडेट के कारण आप गलत डेटा वाली कैश प्रविष्टियों को पुनर्प्राप्त करना शुरू कर सकते हैं।
नीचे स्रोत है। इसका इस्तेमाल करने के लिए स्वतंत्र महसूस करें। मुझे आशा है कि यह मदद करता है।
आयात करें .RedisTemplate;import org.springframework.data.redis.core.SessionCallback;import org.springframework.data.redis.core.script.RedisScript;import org.springframework.data.redis.serializer.RedisSerializer;/** * एक एक्सटेंशन RedisTemplate का जो अपवादों को प्रचारित करने के बजाय लॉग करता है। * यदि रेडिस सर्वर अनुपलब्ध है, तो कैश संचालन हमेशा "मिस" होता है और डेटा डेटाबेस से प्राप्त किया जाता है। */पब्लिक क्लास लॉगिंगरेडिसटेम्पलेट<के, वी> रेडिसटेम्पलेट<के, वी> का विस्तार करता है {निजी स्थिर अंतिम लॉगर लॉगर =लॉगरफैक्टरी.गेट लॉगर(लॉगिंगरेडिसटेम्पलेट.क्लास); @ ओवरराइड पब्लिक <टी> टी निष्पादित करें (अंतिम रेडिस कॉलबैक <टी> क्रिया, अंतिम बूलियन एक्सपोज़कनेक्शन, अंतिम बूलियन पाइपलाइन) {कोशिश करें {वापसी super.execute (कार्रवाई, बेनकाबकनेक्शन, पाइपलाइन); } पकड़ (अंतिम थ्रोबल टी) { logger.warn ("कैश ऑपरेशन निष्पादित करने में त्रुटि:{}", t.getMessage ()); वापसी शून्य; } } @ ओवरराइड पब्लिक <टी> टी निष्पादित करें (अंतिम रेडिसस्क्रिप्ट <टी> स्क्रिप्ट, अंतिम सूची <के> कुंजी, अंतिम ऑब्जेक्ट ... तर्क) {कोशिश करें {वापसी सुपर.निष्पादन (स्क्रिप्ट, कुंजी, तर्क); } पकड़ (अंतिम थ्रोबल टी) { logger.warn ("कैश ऑपरेशन निष्पादित करने में त्रुटि:{}", t.getMessage ()); वापसी शून्य; } } @ ओवरराइड पब्लिक <टी> टी एक्जीक्यूट (फाइनल रेडिसस्क्रिप्ट<टी> स्क्रिप्ट, फाइनल रेडिससेरियलाइजर> आर्ग्ससेरियलाइजर, फाइनल रेडिससेरियलाइजर<टी> रिजल्टसेरियलाइजर, फाइनल लिस्ट<के> कीज, फाइनल ऑब्जेक्ट... आर्ग्स) {कोशिश {रिटर्न super.execute (स्क्रिप्ट, argsSerializer, resultSerializer, कुंजियाँ, args); } पकड़ (अंतिम थ्रोबल टी) { logger.warn ("कैश ऑपरेशन निष्पादित करने में त्रुटि:{}", t.getMessage ()); वापसी शून्य; } } @ ओवरराइड पब्लिक <टी> टी निष्पादित करें (अंतिम सत्र कॉलबैक <टी> सत्र) {कोशिश करें {वापसी super.execute (सत्र); } पकड़ (अंतिम थ्रोबल टी) { logger.warn ("कैश ऑपरेशन निष्पादित करने में त्रुटि:{}", t.getMessage ()); वापसी शून्य; } }}