2012-09-05 10 views
9

तो सिद्धांत 2 का उपयोग कर एक ईमानदारी बाधा उल्लंघन के बाद, EntityManager इस तरह से बंद होना पसंद करता है जो कहा EntityManager का उपयोग करना जारी रखना असंभव बनाता है। प्रचलित विचार यह प्रतीत होता है कि आपको इस सरल अपवाद को पकड़ने और इसे एक सुंदर तरीके से संभालने के लिए एक नया एंटिटी मैनेजर बनाना चाहिए (वहां अद्भुत डिजाइन लोग/कटाक्ष)।बिस्ना/डॉक्टर 2 के साथ एक बंद इकाई प्रबंधक के साथ काम करना

हालांकि एक बंद इकाई प्रबंधक के साथ बिस्ना लाइब्रेरी/जेडएफ 1.12 का उपयोग करते समय एक समस्या उत्पन्न होती है। बिस्ना लाइब्रेरी कंटेनर क्लास में बंद होने के बाद एक ही नाम (यानी "डिफ़ॉल्ट") के साथ एक नया एंटिटी मैनेजर बनाने के लिए सार्वजनिक विधि प्रदान नहीं करती है।

मेरा प्रश्न यह है कि इस मुद्दे से निपटने का सबसे अच्छा तरीका क्या है। एक ईमानदारी बाधा उल्लंघन के बाद आसानी से ठीक होने का एक तरीका होना चाहिए।

+0

सिद्धांत रजिस्ट्री का उपयोग करके बंद इकाई प्रबंधक रीसेट कर सकते हैं। – Florian

+0

देखें https://github.com/symfony/symfony/issues/5339 – Florian

उत्तर

2

इन स्थितियों से उबरने की कोशिश कर की जगह में, आप अखंडता बाधा के उल्लंघन को रोकने पर ध्यान देना चाहिए:

  • आप एक विदेशी कुंजी बाधा मारा, तो आप सही में एक साथ संस्थाओं बांधने नहीं कर रहे हैं तौर तरीका।
  • यदि आप एक अद्वितीय बाधा डालते हैं, तो आपको इसे जारी रखने की कोशिश करने से पहले संभावित डुप्लिकेट डेटा के लिए डीबी की जांच करनी चाहिए।
  • आप बाधा का एक और प्रकार मारा है और यह कैसे को रोकने के लिए पता नहीं है, तो कृपया पूछना :)

अद्यतन:

कारण Doctrine2 बंद कर देता है EntityManager है अधिकांश मामलों में यह है, क्योंकि अब उपयोग करने के लिए सुरक्षित नहीं है। इसके यूनिटऑफवर्क में ऐसे ऑपरेशन होते हैं जो नहीं किए जा सकते हैं (इसलिए अपवाद जो फेंक दिया गया है)।

आप सही हैं कि बिस्ना लाइब्रेरी एक नई EntityManager बनाने का समर्थन नहीं करती है। आप स्वयं को ऐसी कार्यक्षमता को लागू करने के लिए इसे बढ़ा सकते हैं।

एक अन्य समाधान handle transactions manually होगा:

$em->getConnection()->beginTransaction(); // suspend auto-commit 
try { 
    // do some work 
    $user = new User; 
    $user->setName('George'); 
    $em->persist($user); 
    $em->flush(); 
    $em->getConnection()->commit(); 
} catch (Exception $e) { 
    $em->getConnection()->rollback(); 
    $em->clear(); // in stead of $em->close(); 
    throw $e; 
} 

$em->clear() साथ $em->close() बदलकर आप EntityManager खुला और फिर से उपयोग करने के लिए साफ रखें।

मैं उच्च रूप से प्रोत्साहित आप के लिए या तो पास या स्पष्ट EntityManager, डेटा में यह प्रयोग करने योग्य है (लगभग हमेशा) के रूप में नहीं रह गया है।

+1

ऐसे परिदृश्य हैं जब आप पहले से ही संभवतः नहीं जानते हैं। सरल उदाहरण डेटाबेस से जुड़े कई क्लाइंट होने के नाते, जो स्पष्ट रूप से आम है। चेक-इन होने के बाद वे डुप्लिकेट डेटा डाल सकते हैं लेकिन आपके ग्राहक डेटा को सहेजने से पहले। आप केवल इसे अनदेखा नहीं कर सकते हैं, केवल विशिष्ट प्रकार के डेटाबेस ताले का उपयोग करके (और हम वास्तव में उनको नहीं चाहते हैं)। इसलिए इस प्रकार की त्रुटि से पुनर्प्राप्त करना आवश्यक है। –

+0

मैं मानता हूं कि आपको इस विशेष मामले में पुनर्प्राप्त करना चाहिए, लेकिन संभवतः एक ही अनुरोध में एक नई इकाई प्रबंधक की आवश्यकता नहीं होगी (क्योंकि उपयोगकर्ता/ग्राहक को उसके/उसके इनपुट का पुनर्मूल्यांकन करने की आवश्यकता है)। पीएस: सिद्धांत लॉकिंग प्रदान करता है, http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#version और http://docs.doctrine-project.org देखें /en/2.0.x/reference/transactions-and-concurrency.html#locking-support –

0

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

तो अब मेरी कोड इस तरह दिखता है:

try { 
    $user = new User; 
    $user->setName('George'); 
    $em->persist($user); 
    $em->flush(); 
} catch (Exception $e) { 
    $dc = \Zend_Registry::get('doctrine'); //returns Bisna\Doctrine\Container 
    $em = $dc->resetEntityManager(); //returns the new instance 
    throw $e; 
} 

संशोधित कंटेनर वर्ग यहाँ है:

https://github.com/ajlozier/zendframework1-doctrine2/blob/ea46703e909149cba43edca56c91d5de2ab7a7f9/library/Bisna/Doctrine/Container.php