2010-02-25 13 views
9

ए के साथ एक ही समय में नई इकाई बनाएं या मौजूदा इकाई को अपडेट करें। ए में एक जेपीए इकाई है जिसमें टाइमस्टैम्प फ़ील्ड है और इसे जटिल पहचानकर्ता फ़ील्ड द्वारा प्रतिष्ठित किया गया है। मुझे जो चाहिए वह उस इकाई में टाइमस्टैम्प को अपडेट करना है जो पहले ही संग्रहीत हो चुका है, अन्यथा मौजूदा टाइमस्टैम्प के साथ नई इकाई बनाएं और स्टोर करें।जेपीए

जैसा कि यह पता चला है कि यह कार्य उतना आसान नहीं है जितना यह पहली नजर से लगता है। समस्या यह है कि समवर्ती वातावरण में मुझे बुरा "अद्वितीय सूचकांक या प्राथमिक कुंजी उल्लंघन" अपवाद मिलता है। यहां मेरा कोड है:

// Load existing entity, if any. 
Entity e = entityManager.find(Entity.class, id); 
if (e == null) { 
    // Could not find entity with the specified id in the database, so create new one. 
    e = entityManager.merge(new Entity(id)); 
} 
// Set current time... 
e.setTimestamp(new Date()); 
// ...and finally save entity. 
entityManager.flush(); 

कृपया ध्यान दें कि इस उदाहरण में इकाई पहचानकर्ता डालने पर उत्पन्न नहीं होता है, इसे अग्रिम में जाना जाता है।

दो या धागे की अधिक समानांतर में कोड के इस ब्लॉक को चलाते हैं, वे एक साथ nullentityManager.find(Entity.class, id) विधि कॉल से प्राप्त कर सकते हैं, तो वे एक ही पहचानकर्ता त्रुटि में परिणाम के साथ एक ही समय में दो या अधिक संस्थाओं को बचाने के लिए, प्रयास करेंगे ।

मुझे लगता है कि समस्या के कुछ समाधान हैं।

  1. निश्चित रूप से मैं डेटाबेस के समवर्ती उपयोग को रोकने के लिए इस कोड ब्लॉक को वैश्विक लॉक के साथ सिंक्रनाइज़ कर सकता हूं, लेकिन क्या यह सबसे प्रभावी तरीका होगा?
  2. कुछ डेटाबेस बहुत आसान MERGE कथन का समर्थन करते हैं जो मौजूदा अपडेट करता है या कोई भी मौजूद नहीं होने पर नई पंक्ति बनाता है। लेकिन मुझे संदेह है कि ओपनजेपीए (मेरी पसंद का जेपीए कार्यान्वयन) इसका समर्थन करता है।
  3. इवेंट यदि जेपीए एसक्यूएल मेरजे का समर्थन नहीं करता है, तो मैं हमेशा सादे पुराने जेडीबीसी पर वापस आ सकता हूं और जो कुछ भी मैं डेटाबेस के साथ करना चाहता हूं। लेकिन मैं आरामदायक एपीआई और बालों वाले जेडीबीसी + एसक्यूएल संयोजन के साथ गड़बड़ नहीं छोड़ना चाहता हूं।
  4. केवल मानक जेपीए एपीआई का उपयोग करके इसे ठीक करने के लिए एक जादू चाल है, लेकिन मुझे अभी तक यह पता नहीं है।

कृपया मदद करें।

उत्तर

1

आप जेपीए लेनदेन के लेनदेन अलगाव का जिक्र कर रहे हैं। अर्थात। जब वे अन्य लेन-देन के संसाधनों तक पहुंचते हैं तो लेनदेन का व्यवहार क्या होता है। - हां, आपको उपरोक्त कोड के साथ समस्याओं होगा

READ_COMMITTED [..] EJB3 जेपीए का उपयोग कर

इसका मतलब है कि के लिए उम्मीद डिफ़ॉल्ट लेनदेन अलगाव स्तर है:

this article के अनुसार

लेकिन जेपीए कस्टम अलगाव स्तर का समर्थन नहीं करता है।

This thread विषय को अधिक व्यापक रूप से चर्चा करता है। स्प्रिंग या ईजेबी का उपयोग करने के आधार पर, मुझे लगता है कि आप उचित लेनदेन रणनीति का उपयोग कर सकते हैं।

+0

दोनों लिंक टूटे हैं – Sergey