2011-07-14 16 views
5

मेरे वेब एप्लिकेशन में मेरे पास कई थ्रेड हैं जो एक ही डेटा को संभावित रूप से एक्सेस करते हैं, मैंने क्यों आशावादी (संस्करण) और हाइबरनेट के साथ निराशावादी लॉकिंग को लागू करने का निर्णय लिया।किसी इकाई को सही तरीके से लॉक और पुनः लोड करने के लिए कैसे करें

वर्तमान में मैं एक इकाई ताला और (@Transactional साथ स्प्रिंग्स लेन-देन प्रबंधक और लेन-देन सीमांकन का प्रयोग करके) उस पर लिखने कार्रवाई करने निम्नलिखित पैटर्न का उपयोग करें:

@Transactional 
public void doSomething(entity) { 
    session.lock(entity, LockMode.UPGRADE); 
    session.refresh(entity); 

    // I change the entity itself as well as entites in a relationship. 
    entity.setBar(...); 
    for(Child childEntity : entity.getChildren()) { 
     childEntity.setFoo(...); 
    } 
} 

लेकिन, कभी कभी मैं StaleObjectException जब हो रही है @ ट्रांजैक्शनल फ्लशिंग है जो मुझे बताता है कि एक चाइल्डएन्टिटी को समवर्ती रूप से संशोधित किया गया है और अब गलत संस्करण है।

मुझे लगता है मैं कर रहा हूँ सही ढंग से entity और उसके बच्चों रिफ्रेश नहीं हो तो मैं पुराना डेटा के साथ काम कर रहा हूँ। क्या कोई यह बता सकता है कि इसे कैसे प्राप्त किया जाए? मेरे कुछ विचारों में दृढ़ता संदर्भ (सत्र) को साफ़ करना या session.lock(entity, LockMode.READ) को फिर से कॉल करना शामिल था, लेकिन मुझे यकीन नहीं है कि यहां क्या सही है।

आपकी मदद के लिए धन्यवाद!

उत्तर

0

आप "LockMode.UPGRADE" और आशावादी लॉकिंग को एक साथ क्यों रहते हैं? विवादास्पद चीजों की तरह लगता है।

हाइबरनेट कभी भी स्मृति में वस्तुओं को लॉक नहीं करता है और हमेशा डेटाबेस के लॉकिंग तंत्र का उपयोग करता है। साथ ही, "यदि अनुरोधित लॉक मोड डेटाबेस द्वारा समर्थित नहीं है, तो हाइबरनेट एक अपवाद फेंकने के बजाय उपयुक्त वैकल्पिक मोड का उपयोग करता है। यह सुनिश्चित करता है कि अनुप्रयोग पोर्टेबल हैं।" इसका मतलब है, कि यदि आपका डेटाबेस चयन का समर्थन नहीं करता है ... अद्यतन के लिए, शायद, आपको इन अपवादों को प्राप्त होगा।

एक अन्य संभावित कारण यह है कि आपने बच्चों के लिए "org.hibernate.annotations.CascadeType.LOCK" का उपयोग नहीं किया है।

+0

मैं MySQL InnoDB का उपयोग कर रहा हूं जो "चयन ... अद्यतन के लिए" का समर्थन करता है, इसलिए मुझे यहां कोई समस्या नहीं दिखाई दे रही है। इसके अलावा, एक समवर्ती संशोधन किए जाने पर "अधिसूचना" प्राप्त करने के लिए, मैं आशावादी लॉकिंग भी कर रहा हूं। – Erik

+0

क्षमा करें, इस बिंदु को याद किया कि आपको बच्चों के साथ समस्या है (जो बोल्ड में है :))। मैंने जवाब अपडेट किया है ... – Stas

+0

मेरे कोड में मैं हमेशा इकाई को लॉक करता हूं, भले ही मैं केवल इकाई को अद्यतन नहीं करना चाहता हूं। तो लॉक अधिग्रहित भी होना चाहिए। मेरी मुख्य चिंता actuall यह है कि मैं केवल ताज़ा उपयोग करके नवीनतम इकाई/बच्चों के साथ काम नहीं कर रहा हूँ। – Erik

1

आप इस हाइबरनेट-अंक: LockMode.Upgrade doesn't refresh entity values पर विचार करना चाहेंगे।

संक्षेप में: यदि दिया गया इकाई पहले ही लोड हो चुकी है तो हाइबरनेट सफल लॉक के बाद चयन नहीं करता है। लॉक प्राप्त करने के बाद आपको अपने लिए इकाई के लिए ताज़ा करने की आवश्यकता है।

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

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