परिदृश्य: हमारे पास एक स्प्रिंग प्रबंधित वेब एप्लिकेशन है जो वेबस्पेयर के अंदर चलता है। (स्प्रिंग 3.0.एक्स, डब्ल्यूएएस 7) वेबपैप कम्प्यूटेशनल गहन डीबी रीड ऑपरेशंस को निष्पादित करने के लिए स्प्रिंग के WorkManagerTaskExecutor
(10 के थ्रेड पूल आकार के साथ कॉन्फ़िगर किया गया) के माध्यम से वेबस्पेयर के कार्य प्रबंधक का लाभ उठाता है। तो मूल रूप से, उत्पन्न करने के लिए एक अनुरोध आता है, कहें, 10 अलग-अलग दस्तावेज। दस्तावेज़ों को उत्पन्न करने के लिए डेटा एकत्र करने/संसाधित करने के लिए केवल डीबी पढ़ने की आवश्यकता होती है। इसलिए हम मूल रूप से 10 दस्तावेजों को संसाधित करने के लिए 10 धागे उत्पन्न करते हैं और अंत में 10 श्रमिकों से लौटाए गए 10 दस्तावेज इकट्ठा करते हैं और उन्हें मर्ज करते हैं और ग्राहक को एक बड़ी प्रतिक्रिया लिखते हैं। हमने जो पहचाना है वह यह है कि 10 धागे डेटा इकट्ठा/संसाधित कर रहे हैं, जबकि समान डीबी कॉल किए गए समूह हैं। तो हम प्रतिक्रिया के साथ सबसे अधिक निष्पादित डीबी विधियों के आसपास एक पहलू बनाने के लिए क्या आया है। पहलू को सिंगलटन के रूप में कॉन्फ़िगर किया गया है, और पहलू का उपयोग करने वाले कैश को पहलू में स्वचालित रूप से अनुरोध किया जाता है ताकि अनुरोध के लिए सेट किया जा सके ताकि प्रत्येक अनुरोध का अपना कैश हो।एक बहु थ्रेडेड वेब अनुप्रयोग में अनुरोध स्कैन किए गए बीन्स
समस्या: अब इस दृष्टिकोण के साथ समस्या यह है कि जब धागे अपने डीबी कॉल कर रहे हैं और पहलू इंटरजेक्ट कर रहे हैं तो हमें java.lang.IllegalStateException: No thread-bound request found
अपवाद मिल रहा है। जो मैं समझता हूं वह पूरी तरह मान्य है क्योंकि अनुरोध संदर्भ के बाहर धागे निष्पादित किए जा रहे हैं।
क्या इस समस्या को खारिज करने का कोई तरीका है? क्या इन धागे द्वारा बुलाई गई विधियों के लिए अनुरोध स्कॉप्ड कैश के साथ पहलू को लागू करना संभव है?
मैं दृष्टिकोण के बारे में सोचा है, लेकिन एक दोष यह है कि मुझे लगता है कि इसे पारित करने के लिए मुझे मजबूर जाएगा अनन्य अनुरोध पहचानकर्ता सभी विधि कॉल (थ्रेड निष्पादन के दौरान) को डाउनस्ट्रीम करता है जिसे मैं कैश करना चाहता हूं। इसके अलावा, कैश थोड़ी देर के बाद बहुत बड़ा नहीं होगा? जो मुझे समय-समय पर प्रबंधित करने के लिए मजबूर करेगा। शायद मैं यहाँ कुछ याद कर रहा हूँ। – r4j1v
शायद एक "थ्रेड निष्पादन संदर्भ" है जिसका उपयोग मैं अपने अद्वितीय अनुरोध पहचानकर्ता को स्टोर करने के लिए कर सकता हूं और इसे स्वयं को पास किए बिना पहलू में पुनर्प्राप्त कर सकता हूं? – r4j1v
मैं इस मुद्दे के आसपास पाने में कामयाब रहा। मैंने 'WorkManagerTaskExecutor' के बजाय' SimpleAsyncTaskExecutor' का उपयोग शुरू किया। लाभ यह है कि 'SimpleAsyncTaskExecutor' कभी भी थ्रेड का पुन: उपयोग नहीं करेगा। यह केवल आधा समाधान है। समाधान का दूसरा आधा 'RequestContextListener' के बजाय' RequestContextFilter' का उपयोग करना है। 'RequestContextFilter' में' setThreadContextInheritable() 'विधि है जो मूल रूप से बाल धागे को मूल संदर्भ प्राप्त करने की अनुमति देगी। – r4j1v