मुझे केवल-पढ़ने के लिए हाइबरनेट में लेन-देन की आवश्यकता क्यों है?


107

मुझे केवल-पढ़ने के लिए हाइबरनेट में लेन-देन की आवश्यकता क्यों है?

निम्नलिखित लेनदेन डीबी में ताला लगाता है?

उदाहरण कोड DB से लाने के लिए:

Transaction tx = HibernateUtil.getCurrentSession().beginTransaction(); // why begin transaction?
//readonly operation here

tx.commit() // why tx.commit? I don't want to write anything

क्या मैं session.close() इसके बजाय उपयोग कर सकता हूं tx.commit()?


9
लेन-देन की आवश्यकता डीबी द्वारा ही की जाती है। आप यहां ऑटोकॉमिट मोड के बारे में पढ़ सकते हैं: community.jboss.org/wiki/…
Bhesh Gurung

@BheshGurung मुझे लगता है कि हमें केवल लिखने के लिए ट्रांसकेशन की आवश्यकता है
user93796

4
क्या आपने लिंक में "डिबंकिंग ऑटो-कम मिथक" भाग पढ़ा है?
भेश गुरुंग

जवाबों:


131

आपके पास वास्तव में केवल-पढ़ने के लिए लेनदेन को चिह्नित करने के कारण हो सकते हैं।

  1. पढ़ने के लिए लेन-देन वास्तव में अजीब लग सकता है और अक्सर लोग इस मामले में लेनदेन के तरीकों को चिह्नित नहीं करते हैं। लेकिन JDBC किसी भी तरह लेन-देन पैदा करेगा, यह सिर्फ autocommit=trueअगर यह अलग विकल्प स्पष्ट रूप से सेट नहीं किया गया था में काम करेगा ।
  2. लेकिन इस बात की कोई गारंटी नहीं है कि आपका तरीका डेटाबेस में नहीं लिखा है। यदि आप विधि के रूप में चिह्नित करते हैं @Transactional(readonly=true), तो स्प्रिंग JDBC लेनदेन को रीड-ओनली मोड में सेट कर देगा, इस प्रकार आप डिक्टेट करेंगे कि क्या वास्तव में इस लेनदेन के दायरे में DB में लिखना संभव है। यदि आपकी वास्तुकला बोझिल है और टीम के कुछ सदस्य संशोधन क्वेरी डालना चुन सकते हैं, जहाँ यह अपेक्षित नहीं है, तो यह ध्वज आपको समस्या वाले स्थान पर इंगित करेगा।
  3. इसके अलावा केवल पढ़ने के लिए लेनदेन DBs द्वारा अनुकूलित किया जा सकता है, लेकिन यह निश्चित रूप से DB विशिष्ट है। उदाहरण के लिए MySQL ने केवल 5.6.4 संस्करण से शुरू होने वाले InnoDB में इसके लिए समर्थन जोड़ा।
  4. यदि आप सीधे JDBC का उपयोग नहीं कर रहे हैं, बल्कि ORM का उपयोग कर रहे हैं, तो यह समस्याग्रस्त हो सकता है। उदाहरण के लिए हाइबरनेट समुदाय का कहना है कि लेनदेन के बाहर काम करने से अप्रत्याशित व्यवहार हो सकता है। ऐसा इसलिए है क्योंकि हाइबरनेट लेन-देन को खोल देगा, लेकिन यह इसे अपने आप बंद नहीं करेगा, इस प्रकार कनेक्शन को कनेक्शन पूल में लौटा दिया जाएगा, जिसमें लेनदेन प्रतिबद्ध नहीं है। फिर क्या होता है? JDBC चुप्पी बनाए रखता है, इस प्रकार यह विशिष्ट है (MySQL रोल बैक ट्रांजेक्शन, Oracle afair commits)। यह कनेक्शन पूल स्तर पर भी कॉन्फ़िगर किया जा सकता है (जैसे C3P0 आपको ऐसा विकल्प देता है, डिफ़ॉल्ट रूप से रोलबैक)।
  5. एक और बात जब हाइबरनेट की बात आती है, तो स्प्रिंग ने फ्लशमोड को MANUAL को केवल-केवल लेन-देन के मामले में सेट किया है, जो अन्य आशाओं की ओर जाता है जैसे गंदे चेक की कोई आवश्यकता नहीं है।
  6. आप लेन-देन अलगाव स्तर को स्पष्ट रूप से ओवरराइड या सेट करना चाह सकते हैं। यह प्रभाव पढ़े-लेन-देन के साथ-साथ आपके द्वारा किए गए या बिना पढ़े हुए बदलावों को पढ़ना नहीं चाहता है, प्रेत रीडिंग आदि के संपर्क में होना चाहिए।

योग करने के लिए - आप दोनों तरीकों से जा सकते हैं, लेकिन आपको परिणामों को समझने की आवश्यकता है।


जवाब देने के लिए धन्यवाद। मैं हाइबरनेट (देशी हाइबरनेट, जेपीए नहीं) का उपयोग कर रहा हूं। लेकिन हाइबरनेट मुझे किसी भी डीबी ऑपरेशन को करने से पहले ट्रांसकेशन शुरू करने के लिए मजबूर करता है। यदि मैं इसे शुरू नहीं करता हूं तो यह कहता है कि कोई सक्रिय कैस्केनेशन नहीं है। क्या मैं केवल पढ़ने के लिए मार्क ट्रांसकेशन कह रहा हूं। , अगर हाँ तो कैसे?
11:

पठनीय ध्वज वास्तव में कनेक्शन के लिए निर्धारित किया गया है, न कि स्वयं लेनदेन के लिए, और आप इसे हाइबरनेट के माध्यम से इस तरह एक्सेस नहीं कर सकते। आपको स्प्रिंग लेनदेन समर्थन का उपयोग करने और एनोटेशन या XML आधारित लेनदेन कॉन्फ़िगरेशन का उपयोग करने की आवश्यकता है। ऐसा करने से स्प्रिंग हाइबरनेट के बजाय कनेक्शन और लेनदेन प्रबंधन का स्वामित्व लेता है।
स्टेनिस्लाव बश्किर्त्सेव

1
बहुत अच्छी तरह से समझाया! मार्क रिचर्ड्स का एक अन्य लेख ट्रांसएक्शनल एनोटेशन में रीड-ओनली फ्लैग - ibm.com/developerworks/java/library/j-ts1/index.html पर केवल पढ़ने के झंडे के बारे में बहुत अच्छी तरह से बताता है ।
महेश

48

सभी डेटाबेस स्टेटमेंट को एक भौतिक लेनदेन के संदर्भ में निष्पादित किया जाता है, तब भी जब हम स्पष्ट रूप से लेन-देन की सीमाओं (BEGIN / COMMIT / ROLLBACK) की घोषणा नहीं करते हैं

यदि आप लेनदेन की सीमाओं को स्पष्ट रूप से घोषित नहीं करते हैं, तो प्रत्येक विवरण को एक अलग लेनदेन ( autocommitमोड) में निष्पादित करना होगा । यह तब तक प्रति कथन एक कनेक्शन को खोलने और बंद करने की ओर ले जा सकता है जब तक कि आपका वातावरण कनेक्शन-प्रति-थ्रेड बाइंडिंग से निपट नहीं सकता।

एक सेवा की घोषणा के रूप में @Transactionalआप पूरे लेनदेन की अवधि के लिए एक कनेक्शन दे देंगे, और सभी बयान उस एकल अलगाव कनेक्शन का उपयोग करेंगे। यह पहली जगह में स्पष्ट लेनदेन का उपयोग न करने से बेहतर है।

बड़े अनुप्रयोगों पर, आपके पास कई समवर्ती अनुरोध हो सकते हैं, और डेटाबेस कनेक्शन अधिग्रहण अनुरोध दर को कम करने से निश्चित रूप से आपके समग्र आवेदन प्रदर्शन में सुधार होगा।

जेपीए रीड ऑपरेशंस पर लेनदेन लागू नहीं करता है। यदि आप किसी लेन-देन के संदर्भ को शुरू करना भूल जाते हैं, तो केवल एक लेन-देन के अपवाद को फेंकना ही लिखते हैं। फिर भी, केवल-पढ़ने के लिए लेन-देन के लिए भी लेन-देन की सीमाओं की घोषणा करना हमेशा बेहतर होता है (वसंत में @Transactionalआपको रीड-ओनली लेनदेन को चिह्नित करने की अनुमति मिलती है, जिसमें बहुत अच्छा प्रदर्शन होता है)।


1
"... फिर प्रत्येक विवरण को एक अलग लेनदेन में निष्पादित करना होगा"। कंटेनर बैच प्रसंस्करण स्वचालित रूप से नहीं करता है ?
Arash

बैच प्रोसेसिंग संशोधनों के लिए है, डेटा पढ़ने के लिए नहीं। और फिर भी, JPA और हाइबरनेट का उपयोग करते समय JDBC बैचिंग डिफ़ॉल्ट रूप से सक्षम नहीं है।
व्लाद मिहालसी

1
धन्यवाद व्लाद मैंने आपके कुछ लेख पढ़े। वे वास्तव में उपयोगी हैं।
Arash

यह stackoverflow.com/q/34797480/179850 आपके प्रतिज्ञान को थोड़ा विरोधाभास करता प्रतीत होता है कि केवल लेन-देन को पढ़ने से बहुत अच्छा प्रदर्शन लाभ होता है। कम से कम, यह हाइबरनेट के संदर्भ में मामला नहीं लगता है।
निमाई

नहीं, यह नहीं है। यह केवल पढ़ने के लिए सेट करने के बारे में है, जबकि मेरा ऑटो-टाल से बचने के बारे में है।
व्लाद मिहालसी

17

लेन-देन वास्तव में डेटाबेस पर ताले डालते हैं - अच्छे डेटाबेस इंजन समवर्ती ताले को एक समझदार तरीके से संभालते हैं - और यह सुनिश्चित करने के लिए केवल पढ़ने के उपयोग के साथ उपयोगी होते हैं कि कोई अन्य लेनदेन डेटा को जोड़ता नहीं है जो आपके विचार को असंगत बनाता है। आप हमेशा एक लेन-देन चाहते हैं (हालांकि कभी-कभी यह अलगाव स्तर को ट्यून करने के लिए उचित है, यह सबसे अच्छा नहीं है कि इसके साथ शुरू करें); यदि आप अपने लेन-देन के दौरान कभी भी DB को नहीं लिखते हैं, तो लेनदेन को वापस करने और वापस करने दोनों एक ही (और बहुत सस्ते) हो जाते हैं।

अब, यदि आप भाग्यशाली हैं और DB के खिलाफ आपके प्रश्न ऐसे हैं कि ORM हमेशा उन्हें एकल SQL प्रश्नों के लिए मैप करता है, तो आप स्पष्ट लेनदेन के बिना दूर हो सकते हैं , DB के अंतर्निहित ऑटोकॉमिट व्यवहार पर भरोसा करते हैं, लेकिन ORM अपेक्षाकृत जटिल प्रणाली हैं इसलिए यह इस तरह के व्यवहार पर भरोसा करने के लिए सुरक्षित नहीं है जब तक कि आप बहुत अधिक काम की जाँच नहीं करते कि कार्यान्वयन वास्तव में क्या करता है। स्पष्ट लेन-देन की सीमाओं को लिखना सही होना बहुत आसान है (विशेषकर यदि आप इसे AOP या कुछ इसी तरह की ओआर-चालित तकनीक से कर सकते हैं, तो जावा 7 के बाद से कोशिश-के-संसाधनों का उपयोग किया जा सकता है, मुझे भी लगता है)।


14

इससे कोई फर्क नहीं पड़ता है कि आप केवल पढ़ते हैं या नहीं - डेटाबेस को अभी भी आपके परिणाम का ट्रैक रखना चाहिए, क्योंकि अन्य डेटाबेस क्लाइंट डेटा लिखना चाहते हैं जो आपके परिणाम को बदल देगा।

मैंने विशाल डेटाबेस सिस्टम को मारने के लिए दोषपूर्ण कार्यक्रमों को देखा है, क्योंकि वे सिर्फ डेटा पढ़ते हैं, लेकिन कभी भी प्रतिबद्ध नहीं होते हैं, लेन-देन लॉग को बढ़ने के लिए मजबूर करते हैं, क्योंकि डीबी एक संचार या रोलबैक से पहले लेनदेन डेटा जारी नहीं कर सकता है, भले ही ग्राहक ने कुछ भी नहीं किया हो घंटों तक।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.