2010-06-07 9 views
8

मैं थ्रेड का उपयोग करने के लिए अपने जेपीए कोड को बदलने के बीच में हूं। मेरे पास प्रत्येक थ्रेड के लिए एक अलग इकाई प्रबंधक और लेनदेन है।जेपीए परमाणु क्वेरी/बहुप्रचारित ऐप के लिए सहेजें

// get object from the entity manager 
X x = getObjectX(jpaQuery); 

if(x == null) 
{ 
    x = new X(); 
    x.setVariable(foo); 
    entityManager.persist(x); 
} 
बहु थ्रेडेड वातावरण मैं डुप्लिकेट चाबी मिल रहा है, के बाद से मुझे लगता है कि कोड के साथ

, getObjectX एक के लिए अशक्त रिटर्न:

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

तुल्यकालन में जोड़ने के लघु, वहां पहुंचने के लिए एक परमाणु तरीका है/बचाने-अगर-नहीं करता-अस्तित्व जेपीए के साथ एक मूल्य या मैं अपने दृष्टिकोण पर पुनर्विचार करना चाहिए

संपादित करें:

मैं उपयोग कर रहा हूँ नवीनतम Eclipselink और MySQL 5.1

संपादित करें 2:

मैं तुल्यकालन ... बड़े पैमाने पर प्रदर्शन हिट (बात करने के लिए है कि यह नहीं किया जा सकता) जोड़ा गया। मुख्य धागे पर सभी डेटा एकत्र करने के लिए जा रहे हैं और फिर उस धागे पर रचनाएं करें।

उत्तर

4

संक्षिप्त दुखद उत्तर नहीं है कि जेपीए एपीआई आपके लिए ऐसा नहीं कर सकता है। संपूर्ण एपीआई काम करने जा रहे हैं और समवर्ती संशोधन की स्थिति में अपवाद फेंकने के आशावादी सिद्धांत के चारों ओर कम या कम बनाया गया है।

यदि यह अक्सर होता जा रहा है, तो संभवतः कुछ अन्य घटक (जो भी foo उत्पन्न करता है?) है जो थ्रेडसेफ बनाने से लाभ प्राप्त कर सकता है, शायद क्वेरी के आसपास सिंक्रनाइज़ करने का विकल्प + बनाना।

+0

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

2

मुझे लगता है कि आपको "jpaQuery" में उपयोग किए जाने वाले फ़ील्ड पर एक अनूठी बाधा जोड़ने की आवश्यकता होगी ताकि डेटाबेस उस क्वेरी के लिए बाधाओं में उपयोग किए गए समान मानदंडों के साथ डुप्लिकेट पंक्तियां नहीं बना सके। कॉलिंग कोड को परिणामी अपवाद को फँसाने की आवश्यकता होगी जो बाधा उल्लंघन के परिणामस्वरूप होती है (आदर्श रूप से यह एक EntityExistsException होगी, लेकिन इस मामले पर कल्पना स्पष्ट नहीं है)।

+0

मेरे पास अद्वितीय बाधाएं हैं, और मुझे अपवाद मिल रहा है। मैं अपवाद उठाए बिना इसे करने का कोई तरीका ढूंढने की उम्मीद कर रहा था ... – TofuBeer

+1

अपवाद का उपयोग करना शायद इस परिदृश्य में सबसे आसान समाधान है, यह आशावादी लॉकिंग के समान है जो विफलता पर अपवाद का भी उपयोग करता है। –

0

क्या आप वाकई कई इकाई प्रबंधकों की आवश्यकता है?

private Object customerLock = new Object[0]; 

public Customer createCustomer(){ 
    Customer customer = new Customer(); 
    synchronized(customerLock){ 
     entityManager.persist(customer); 
    } 
    return customer; 
} 

संपादित करें:: इसी तरह की स्थिति में, मैं सिर्फ एक entitymanager और सरल प्रति-विधि ताला वस्तुओं का उपयोग ठीक है, कह रही है कि यह मेरी क्षुधा में ठीक प्रदर्शन को छोड़कर प्रदर्शन के बारे में ज्यादा कुछ नहीं कर सकता है, लेकिन विशिष्टता के लिए इस तरह कुछ उपयोग करें:

public Customer getOrCreateCustomer(String firstName, String lastName){ 
    synchronized(customerLock){ 
     List<Customer> customers = 
      entityManager.createQuery(
       "select c from Customer c where c.firstName = :firstName" 
       + " and c.lastName = :lastName" 
      ) 
      .setParam("firstName", firstName) 
      .setParam("lastName", lastName) 
      .setMaxResults(1) 
      .getResultList(); 
     if(customers.isEmpty()){ 
      Customer customer = new Customer(firstName, lastName); 
      entityManager.persist(customer); 
     }else{ 
      customer = customers.get(0); 
     } 
    } 
    return customer; 
} 
+0

मुझे यह सुनिश्चित करने की ज़रूरत है कि ऑब्जेक्ट, आपके मामले में, ग्राहक पहले से मौजूद नहीं है। मैंने सिंक्रनाइज़ेशन जोड़ने की कोशिश की लेकिन प्रदर्शन खराब था। – TofuBeer

+0

जावा-स्तरीय सिंक्रनाइज़ेशन क्लस्टर – Vadzim

3

कुछ "हैक" पर विचार करने के लिए:

  • लागू hashCode() और equals() वस्तुओं के व्यापार प्रमुख (नहीं उत्पन्न आईडी)
  • पर सिंक्रनाइज़ के आधार पर:

    (obj.getClass().getName() + String.valueOf(hashCode())).intern() 
    

इस प्रकार आप केवल प्रासंगिक मामलों में ताले पाएंगे।

+0

हम्म ... मेरे पास पहले से ही ऐसे बराबर/हैश कोड हैं ... कभी भी उन पर सिंक्रनाइज़ करने के बारे में सोचा नहीं। मैं इसे देखने के लिए सिर्फ एक शॉट दे दूंगा। – TofuBeer

+0

यह चालाक है :-) –

+0

यह क्लस्टर में काम नहीं करेगा – Vadzim

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