2008-09-17 6 views
17

हाइबरनेट की मेरी समझ यह है कि वस्तुओं को डीबी से लोड किया जाता है, उन्हें सत्र में जोड़ा जाता है। विभिन्न बिंदुओं पर, आपकी कॉन्फ़िगरेशन के आधार पर, सत्र फ़्लश हो जाता है। इस बिंदु पर, संशोधित वस्तुओं को डेटाबेस में लिखा जाता है।जब हाइबरनेट एक सत्र को फहराता है, तो यह कैसे तय करता है कि सत्र में कौन सी वस्तुएं गंदे हैं?

हाइबरनेट कैसे तय करता है कि कौन सी वस्तुएं 'गंदे' हैं और उन्हें लिखे जाने की आवश्यकता है?

फ़ील्ड में हाइबरनेट इंटरसेप्ट असाइनमेंट द्वारा उत्पन्न प्रॉक्सी करें, और ऑब्जेक्ट को सत्र में गंदे सूची में जोड़ें?

या हाइबरनेट सत्र में प्रत्येक ऑब्जेक्ट को देखता है और वस्तुओं की मूल स्थिति के साथ इसकी तुलना करता है?

या कुछ पूरी तरह से अलग है?

उत्तर

22

हाइबरनेट बाइटकोड पीढ़ी (सीजीआईएलबी) का उपयोग/कर सकता है ताकि यह पता चल सके कि जैसे ही आप सेटर को कॉल करते हैं (या यहां तक ​​कि क्षेत्र के उपक्रम को भी निर्दिष्ट करते हैं)।

यह तुरंत उस क्षेत्र/वस्तु को गंदे के रूप में चिह्नित करता है, लेकिन फ्लश के दौरान गंदे-जांच की जाने वाली वस्तुओं की संख्या को कम नहीं करता है। यह सब org.hibernate.engine.EntityEntry.requiresDirtyCheck() के कार्यान्वयन को प्रभावित करता है। यह अभी भी गंदगी की जांच के लिए क्षेत्र-दर-क्षेत्र तुलना करता है।

मैं ऊपर बताता हूं कि स्रोत कोड (3.2.6 जीजी) के माध्यम से हालिया ट्रैवल पर आधारित है, जो भी जो भी विश्वसनीयता जोड़ता है। ब्याज के अंक हैं:

  • SessionImpl.flush() एक onFlush() घटना से चलाता है।
  • SessionImpl.list()autoFlushIfRequired() पर कॉल करता है जो onAutoFlush() ईवेंट ट्रिगर करता है। (ब्याज की मेज पर)। यही है, प्रश्न फ्लश का आह्वान कर सकते हैं। दिलचस्प बात यह है कि कोई लेनदेन नहीं होने पर कोई फ्लश नहीं होता है।
  • दोनों घटनाएं अंततः AbstractFlushingEventListener.flushEverythingToExecutions() में समाप्त होती हैं, जो flushEntities() पर समाप्त होती है (अन्य दिलचस्प स्थानों के साथ)।
  • वह सत्र में प्रत्येक इकाई (source.getPersistenceContext().getEntityEntries()) पर 0,पर कॉल करता है।
  • अंत में आप dirtyCheck() पर समाप्त हो जाते हैं। यह विधि कुछ अनुकूलन को CGLIB गंदे झंडे के लिए wrt बनाती है, लेकिन हम अभी भी प्रत्येक इकाई पर लूपिंग समाप्त कर चुके हैं।
+0

कृपया, बेहतर समझाएं: यदि गंदा ध्वज उन वस्तुओं की संख्या को कम नहीं करता है जिन्हें गंदे-जांच की आवश्यकता है, तो इसकी उपयोगिता क्या है? स्रोत में फ़र्टरमोर मैं दो अलग गंदे झंडे देखता हूं: एक सारफिल्ल्डइंटरसेप्टर में है और EntityEntry.requiresDirtyCheck() द्वारा चेक किया गया है, दूसरा एक सार तत्वों में बदलाव है और टिप्पणी की गई है "संग्रह उनके सार्वजनिक इंटरफ़ेस के माध्यम से किए गए परिवर्तनों का पता लगाते हैं और खुद को प्रदर्शन के रूप में गंदे के रूप में चिह्नित करते हैं अनुकूलन "(मुझे नहीं पता कि यह कोड में कहां चेक किया गया है)। – Pino

+0

@ मैट क्वाइल, मुझे गंदे झंडे नहीं मिल रहे थे जिनके बारे में आप बात कर रहे हैं, केवल वही है जिसका उपयोग केवल तब किया जा सकता है जब बिल्डटाइम बाइटकोड उपकरण का उपयोग किया जाता है। –

5

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

+0

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

1

सत्र में प्रत्येक तत्व org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck को एक नजर डालें इस विधि को जाता है अगर यह (कैश से एक या एक एक अछूता संस्करण के साथ तुलना करके गंदा है या नहीं यह निर्धारित करने के डेटाबेस से)।

1

Hibernate default dirty checking mechanism वर्तमान संलग्न इकाइयों को पार करेगा और उनके प्रारंभिक लोडिंग-टाइम मानों के विरुद्ध सभी गुणों से मेल खाता है।

बेहतर होगा कि तुम निम्न चित्र में इस प्रक्रिया को कल्पना कर सकते हैं:

Default automatic dirty checking

0

ये जवाब अधूरे हैं (कम से सबसे अच्छा - मैं यहाँ एक विशेषज्ञ नहीं हूँ)। यदि आपके सत्र में आपके पास एक हिब मैन इकाई है, तो आप इसे कुछ भी नहीं करते हैं, फिर भी आप उस पर जारी एक अपडेट प्राप्त कर सकते हैं जब आप इसे सेव() पर कॉल करते हैं। कब? जब कोई अन्य सत्र आपके लोड() और सेव() के बीच उस ऑब्जेक्ट को अपडेट करता है। यहां मेरा उदाहरण है: hibernate sets dirty flag (and issues update) even though client did not change value

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