2017-10-18 16 views
5

मुझे इस विषय के बारे में बहुत सी पोस्ट मिलीं, लेकिन सभी उत्तर दस्तावेजों के लिंक थे, उदाहरण के साथ कोई उदाहरण कोड नहीं, यानी अभ्यास में समरूपता का उपयोग कैसे करें।वसंत में हाइबरनेट के साथ Concurrency

मेरे स्थिति: मैं के साथ एक इकाई House है (simplyfication के लिए) दो गुणधर्म हैं number (आईडी) और owner। डेटाबेस को के साथ number 1-10 और owner हमेशा null के साथ प्रारंभ किया गया है।

मैं वर्तमान में कोई मालिक नहीं, और सबसे छोटा number घर के साथ एक नया मालिक असाइन करना चाहता हूं। ,

@Transactional 
void assignNewOwner(String newOwner) { 
    //this is flagged as @Transactional too 
    House tmp = houseDao.getHouseWithoutOwnerAndSmallestNumber(); 

    tmp.setOwner(newOwner); 

    //this is flagged as @Transactional too 
    houseDao.update(tmp); 
} 

मेरी समझ के लिए हालांकि @Transactional प्रयोग किया जाता है, एक ही House, विभिन्न मालिकों के लिए दो बार सौंपा जा सकता है अगर दो अनुरोध एक ही खाली Housetmp के रूप में लाने: मेरे कोड इस तरह दिखता है। मैं कैसे सुनिश्चित करूं कि ऐसा नहीं हो सकता है?

मुझे पता है, खाली House के चयन में अद्यतन सहित समस्या हल हो जाएगी, लेकिन निकट भविष्य में, मैं tmp ऑब्जेक्ट के साथ संशोधित/काम करना चाहता हूं।

+1

'houseDao.update (tmp); 'अनावश्यक है, क्योंकि' tmp' एक प्रबंधित इकाई है (आप एक लेनदेन विधि में हैं)। अलग-अलग 'अपडेट() 'की आवश्यकता के बिना परिवर्तन जारी रहेगा। – Kayaman

उत्तर

1

आशावादी

आप अपनी इकाई/मेज पर एक संस्करण स्तंभ जोड़ने, तो आप एक तंत्र आशावादी लॉकिंग कहा जाता है का लाभ ले सकता है । यह सुनिश्चित करने का सबसे कुशल तरीका है कि एक इकाई की स्थिति बदल नहीं गई है क्योंकि हमने इसे एक लेनदेन संदर्भ में प्राप्त किया है।

एक बार जब आप createQuery का उपयोग कर session आप तो कहते हैं setLockMode(LockModeType.OPTIMISTIC);

फिर, बस से पहले लेन-देन के लिए प्रतिबद्ध है, हठ प्रदाता उस संस्था के वर्तमान संस्करण के लिए क्वेरी और जाँच करें कि क्या यह एक और लेन-देन से वृद्धि की गई है हैं कर सकते हैं । यदि ऐसा है, तो आपको आशावादी लॉक अपवाद और लेनदेन रोलबैक मिलेगा।

निराशावादी

आप संस्करण अपनी पंक्तियों नहीं करते हैं, तो आप निराशावादी लॉक-इन के साथ छोड़ दिया जाता है मूल रूप से जिसका अर्थ है कि आप phycically नहीं पढ़ सकते हैं/अद्यतन उन डेटाबेस स्तर पर प्रश्नों संस्थाओं और अन्य लेनदेन के लिए एक लॉक बनाना कुछ पंक्तियां

आपको लगता है कि लक्ष्य को हासिल Query वस्तु पर इस सेटिंग के द्वारा:

setLockMode(LockModeType.PESSIMISTIC_READ);

या

setLockMode(LockModeType.PESSIMISTIC_WRITE);

1

वास्तव में यह बहुत आसान है - कम से कम मेरी राय में है और मैं सार करने जा रहा हूँ जब आप Pessimistic/Optimistic कहते हैं तो Hibernate से उत्पन्न होगा। आपको लगता है कि यह SELECT FOR UPDATE है - लेकिन यह हमेशा मामला नहीं है, MSSQL AFAIK में यह नहीं है ...

ये JPA एनोटेशन हैं और वे कुछ कार्यक्षमता की गारंटी देते हैं, कार्यान्वयन नहीं।

मूल रूप से वे पूरी तरह से अलग-अलग चीजें हैं - PESSIMISTIC बनाम OPTIMISTIC लॉकिंग। जब आप निराशावादी लॉकिंग करते हैं तो आप कम से कम तर्कसंगत रूप से synchronized block करते हैं - आप जो भी चाहें कर सकते हैं और आप लेनदेन के दायरे में सुरक्षित हैं। अब, row, table or even page के लिए लॉक जो भी हो रहा है वह निर्दिष्ट नहीं है; इतना थोड़ा खतरनाक। आमतौर पर डेटाबेस ताले बढ़ सकता है, एमएसएसएलएलएल करता है कि अगर मैं सही ढंग से फिर से कॉल करता हूं।

जाहिर है लॉक भुखमरी एक मुद्दा है, इसलिए आपको लगता है कि OPTIMISTIC लॉकिंग मदद करेगा। एक साइड नोट के रूप में, यह transactional memory is in modern CPU है; वे एक ही सोच प्रक्रिया का उपयोग करते हैं।

तो आशावादी रूप से लॉकिंग कहने की तरह है - मैं इस पंक्ति को आईडी/दिनांक आदि के साथ चिह्नित करूंगा, फिर मैं इसका स्नैपशॉट ले जाऊंगा और इसके साथ काम करूंगा - इससे पहले कि मैं यह जांच करूँगा कि आईडी आईडी बदल गई है या नहीं। जाहिर है कि ID पर विवाद है, लेकिन डेटा पर नहीं। अगर यह बदल गया है - abort (उर्फ फेंक OptimisticLockException) अन्यथा काम करते हैं।

यह बात जो हर किसी को आईएमओ परेशान करती है वह है कि OptimisticLockException - आप इससे कैसे ठीक हो जाते हैं? और यहां कुछ ऐसा है जिसे आप पसंद नहीं करेंगे - यह पर निर्भर करता है। ऐसे ऐप्स हैं जहां एक साधारण पुनः प्रयास पर्याप्त होगा, ऐसे ऐप्स हैं जहां यह असंभव होगा। मैंने दुर्लभ परिदृश्यों में इसका इस्तेमाल किया है।

मैं आमतौर पर Pessimistic लॉकिंग के साथ जाता हूं (जब तक Optimistic पूरी तरह से एक विकल्प नहीं है)। उसी समय मैं उस क्वेरी के लिए हाइबरनेट उत्पन्न करता हूं। उदाहरण के लिए आपको के लिए वास्तव में को केवल को लॉक करने के लिए index की आवश्यकता हो सकती है - क्योंकि आखिरकार वह वही है जो आप चाहते हैं।

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