2010-01-04 13 views
9

इस questionहाइबरनेट क्वेरी कैश - ऑब्जेक्ट्स के लिए दूसरे स्तर के कैश में नहीं - जोखिम भरा? उपयोगी? बुरा अभ्यास?

परिसर से संबंधित:

ये मेरी मान्यताओं, मेरे पढ़ने, अनुभव और समझ के आधार पर कर रहे हैं, वे गलत हो सकता है अगर वे कर रहे हैं, कृपया टिप्पणी और मैं प्रश्न को संपादित करेंगे ।

  • क्वेरी कैश ज्यादातर 2 स्तर कैश के साथ अच्छा है
  • क्वेरी कैश कैश प्रश्नों + मापदंडों के पहचानकर्ता परिणाम
  • क्वेरी कैश जोखिम भरा है, तो डेटाबेस बदल गया था, और यह करने के लिए परिलक्षित नहीं किया गया था कैश

प्रश्न:

मैं एक वस्तु है कि 2 स्तर कैश में नहीं है। कुछ खराब प्रोग्रामिंग या अन्य बाधाओं के कारण, ऑब्जेक्ट को लोड करने वाला कोड उसी हाइबरनेट सत्र में कई बार कहा जा रहा है। आगमन एक एचक्यूएल खोज क्वेरी उदा।

hibernateTemplate.find("from Foo f where f.bar > ?", bar); 

, क्वेरी कैश जोड़ने यदि उपरोक्त कोड एक ही हाइबरनेट सत्र के भीतर N बार बुलाया गया था पहले, वहाँ थे एन डेटाबेस

तो मैं देखने के लिए अगर मैं क्वेरी कैश क्या होता है चाहता था करने के लिए हिट:

Query query = session.createQuery("from Foo f where f.bar > ?"); 
query.setCacheable(true); 
query.setParameter(bar); 
query.list(); 

जब मैं क्वेरी कैश कहा, मैंने देखा है कि एक ही सत्र के दौरान, हाइबरनेट डेटाबेस N बार अब और प्रति सत्र हिट नहीं करता, केवल एक बार।

  1. तो मेरी पहली धारणा यह है कि हाइबरनेट पहली बार सत्र कैश में खोज करता है, फिर दूसरे स्तर के कैश में। क्या यह धारणा सही है?
  2. मुझे यह भी लगता है कि यदि ऑब्जेक्ट (Foo) जो कि दूसरे स्तर के कैश में नहीं है, तो डेटाबेस में बदल दिया गया था, फिर क्वेरी कैश, क्रॉस सत्र स्कॉप्ड होने पर गलत पहचानकर्ता और इस प्रकार गलत ऑब्जेक्ट्स लौटाएंगे। क्या वो सही है?
  3. क्या यह कहना सुरक्षित है कि प्रश्नों के लिए क्वेरी कैश का उपयोग करना जिसमें गैर 2 एल कैश किए गए ऑब्जेक्ट्स के लिए अपरिवर्तनीय जानकारी शामिल है, एक अच्छा अभ्यास है? (उदाहरण के लिए एक प्रश्न है कि इसकी जहां खंड एक शर्त है कि हमेशा एक ही परिणाम देंगी, जैसे होता है जब ser_num और आईडी जोड़ों नहीं बदल एक बार बनाया है "जहां p.id =? P.ser_num चुनें")

तक वैसे, संबंधित question में दावा किया गया है कि क्वेरी कैश सत्र कैश स्कोप पर काम नहीं करता है। क्या मैं उस दावे को याद कर रहा हूं, या कुछ और?

+3

+1 उत्कृष्ट रूप से गठित, स्वरूपित और शोध किए गए प्रश्न के लिए +1। –

उत्तर

5

एक क्वेरी कैश 2 स्तर कैश की एक विशेष प्रकार है । जिसे आप दूसरे स्तर के कैश के रूप में संदर्भित करते हैं, मैं "ऑब्जेक्ट कैश" को कॉल करना पसंद करूंगा। अपनी मान्यताओं पर

टिप्पणियाँ:

  • क्वेरी कैश ज्यादातर 2 स्तर कैश के साथ अच्छा है (उर्फ कैश वस्तु)।

एक क्वेरी कैश केवल प्राथमिक कुंजी के रूप में प्रश्नों के कच्चे परिणाम रखती है, हाइबरनेट में बात करते हैं, पहचान-पत्र। यह वास्तविक हाइड्रेटेड वस्तुओं को पकड़ नहीं है। यह समझ में आता है जब आप jdbc के साथ एक क्वेरी निष्पादित करते हैं, तो यह वास्तव में आपको परिणामस्वरूप हाइड्रेटेड (पॉप्युलेट) ऑब्जेक्ट्स देता है जैसा कि आप परिणामसेट पर फिर से करते हैं। बयान जरूरी नहीं है। यदि क्वेरी बहुत जटिल है और इस प्रकार क्वेरी कैश का उपयोग करके चलाने में बहुत लंबा समय लगता है, तो आप उस समय को सहेज लेंगे। आप क्वेरी कैश का उपयोग करके नहीं करेंगे, डेटाबेस से वस्तुओं को लोड करने में लगने वाले समय को बचाएं।

  • क्वेरी कैश जोखिम भरा है, तो डेटाबेस बदल गया था, और यह कैश

यह सच है के लिए परिलक्षित नहीं था, लेकिन यह कैश क्वेरी करने के लिए अद्वितीय नहीं है , जो भी आप दूसरे स्तर के कैश शब्द के लिए सच रखते हैं, लेकिन आमतौर पर ऑब्जेक्ट कैश कहलाता है।

तो मेरी पहली धारणा है कि हाइबरनेट पहले खोजें सत्र कैश में है, तो 2 स्तर कैश में। क्या यह धारणा सही है?

हाँ, जब वस्तुओं लोड हो रहा है इस व्यवहार है।

मैं भी मान लेते हैं कि अगर वस्तु (फू) जो 2 स्तर कैश में नहीं है, डेटाबेस में बदल गया था, तो क्वेरी कैश, किया जा रहा पार सत्र scoped, गलत वापस आ जाएगी पहचानकर्ता, और इस प्रकार गलत ऑब्जेक्ट्स। क्या वो सही है?

हां, ऑब्जेक्ट कैश और क्वेरी कैश दोनों प्रभावित होंगे। यह केवल चिंता का विषय है यदि डेटाबेस हाइबरनेट के माध्यम से बिना बदला जाता है। आप क्वेरी कैश के टाइमआउट को सेट करके संभावित रूप से इसके प्रभाव को कम कर सकते हैं।

यह तो कहना है कि प्रश्नों कि यहां तक ​​कि गैर 2L कैश की गई वस्तुओं के लिए अपरिवर्तनीय जानकारी शामिल है, के लिए क्वेरी कैश का उपयोग कर एक अच्छा अभ्यास है सुरक्षित है? (जैसे एक प्रश्न है कि इसकी जहां खंड एक शर्त है कि हमेशा समान परिणाम देगी होता है, उदाहरण के लिए "का चयन p.ser_num जहां p.id =?" जब ser_num और आईडी जोड़ों एक बार बनाया न बदलें)

इस तरह की वस्तुओं के लिए ऑब्जेक्ट कैश और क्वेरी कैश दोनों का उपयोग न करने का कोई कारण नहीं है।

और हाँ, क्वेरी कैश सत्र स्तर उर्फ ​​स्तर 1 कैश पर काम नहीं करता है। इस प्रकार जब आप फिर से क्वेरी निष्पादित करते हैं तो यह डेटाबेस को फिर से हिट करता है। यह सत्र कैश में एक क्वेरी के परिणाम (आईडी सेट) नहीं डालेगा।

+0

बहुत गहन जवाब के लिए धन्यवाद, एक बात जो मुझे समझ में नहीं आती है। जब आपने लिखा "यह सत्र कैश में एक क्वेरी का परिणाम (आईडी सेट) नहीं डालेगा।" - जब यह "डेटाबेस को फिर से हिट करता है" तो क्या यह क्वेरी निष्पादित करता है? या सिर्फ आईडी में "चयन करें" क्वेरी में वस्तुओं को लोड करता है? जब सत्र का दायरा खत्म हो जाता है, क्वेरी कैश को अभी भी ids को पकड़ना चाहिए, भले ही वे किसी ऑब्जेक्ट के दूसरे स्तर के कैश में न हों, है ना? –

+0

यदि क्वेरी कैश्ड क्वेरी नहीं है तो यह हर बार (पूर्ण क्वेरी) डेटाबेस को हिट करेगा, जैसा आपने देखा था। यदि यह कैश करने के लिए कॉन्फ़िगर किया गया है, तो यह पहली बार डेटाबेस को हिट करेगा और फिर नहीं। मैं आपको सुझाव दूंगा कि आप या तो हाइबरनेट पैरामीटर या सेटिंग org.hibernate.SQL से DEBUG पर SQL लॉगिंग चालू करें ताकि आप डेटाबेस को मार रहे हों तो ठीक से देख सकें। –

2

केवल मान्यताओं:

इस article हाइबरनेट प्रलेखन से के अनुसार: (एक पकड़े कैश्ड क्वेरी परिणाम सेट ऑर्ग:

[क्वेरी कैश] दो नए कैश क्षेत्रों बनाता है .hibernate.cache.StandardQueryCache), के अन्य होल्डिंग टाइमस्टैम्प क्वेरी करने योग्यके हालिया अपडेटटेबल (org.hibernate.cache.UpdateTimestampsCache)।

मैं इसका मतलब यह है कि जब भी queryable तालिका के टाइमस्टैम्प परिणाम निर्धारित से अधिक नया मान - यह हाइबरनेट उस क्वेरी के लिए अगली कॉल में डीबी दृष्टिकोण का कारण होगा, और कहा कि क्या क्वेरी कैश रखने कुछ पहलू में सुरक्षित

लेकिन 2 वाक्य बाद में प्रलेखन का एक ही पैराग्राफ में यह कहते हैं:

क्वेरी कैश हमेशा दूसरे स्तर कैश के साथ संयोजन के रूप में इस्तेमाल किया जाना चाहिए।

फिर, मेरे इस धारणा है कि यह है एक ही रास्ता हाइबरनेट डेटाबेस है कि इस विशिष्ट उपयोगकर्ता के सत्र से बाहर किया जाता है में परिवर्तन के बारे में पता किया जा सकता है

+0

+1 बहुत अच्छा जवाब –

1

आपके प्रश्न # 3 के लिए, मुझे नहीं लगता कि जब आप कैश नहीं किए जाते हैं तो आप क्वेरी कैश का उपयोग करना चाहते हैं। आप सभी प्राथमिक आईडी के साथ समाप्त हो जाएंगे, लेकिन ऑब्जेक्ट्स को पुनर्प्राप्त करने के लिए प्रति कुंजी एक बार डाटाबेस को हिट करना होगा जो बिना किसी कैशिंग के क्वेरी चलाने से धीमे हो सकते हैं। वैसे भी 3.3 के रूप में, शायद नए संस्करणों में यह कम प्रश्नों का उपयोग कर लापता वस्तुओं को पकड़ लेता है, उदा। जहां आईडी में (: id1,: id2, ...)।

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