इस तरह मैंने डॉक्ट्रिन को हल किया "एंटिटी मैनजर बंद है।" मुद्दा। मूल रूप से हर बार एक अपवाद (यानी डुप्लिकेट कुंजी) या अनिवार्य कॉलम के लिए डेटा प्रदान नहीं करना डोक्ट्रीन को एंटिटी मैनेजर को बंद करने का कारण होगा। यदि आप अभी भी डेटाबेस के साथ बातचीत करना चाहते हैं तो आपको JGrinonresetManager()
द्वारा बताए गए तरीके से कॉल करके Entity Manger को रीसेट करना होगा ।
मेरे आवेदन में मैं कई RabbitMQ उपभोक्ताओं को चला रहा था जो सभी एक ही काम कर रहे थे: अगर कोई इकाई डेटाबेस में थी, तो जाँच करें कि यदि हाँ, तो इसे वापस लौटाएँ, यदि नहीं बनाते हैं और फिर इसे वापस करते हैं। जाँच के बीच कुछ मिलीसेकंड में अगर वह इकाई पहले से मौजूद थी और इसे बनाने वाला एक अन्य उपभोक्ता भी ऐसा ही करता था और लापता इकाई को एक नकली कुंजी अपवाद ( दौड़ की स्थिति ) में अन्य उपभोक्ता को उकसाता है ।
इससे सॉफ्टवेयर डिजाइन की समस्या पैदा हो गई। मूल रूप से मैं जो करने की कोशिश कर रहा था, वह सभी संस्थाओं को एक लेन-देन में पैदा कर रहा था। यह सबसे स्वाभाविक लग सकता है लेकिन निश्चित रूप से मेरे मामले में वैचारिक रूप से गलत था। निम्नलिखित समस्या पर विचार करें: मुझे एक फुटबॉल मैच इकाई को स्टोर करना था जिसमें ये निर्भरताएं थीं।
- एक समूह (जैसे समूह A, समूह B ...)
- एक दौर (जैसे सेमीफाइनल ...)
- एक स्थान (यानी जहां मैच हो रहा है स्टेडियम)
- एक मैच की स्थिति (जैसे आधा समय, पूर्णकालिक)
- मैच खेलने वाली दो टीमें
- मैच ही
अब, स्थल का निर्माण मैच के समान लेनदेन में क्यों होना चाहिए? यह हो सकता है कि मुझे सिर्फ एक नया स्थान प्राप्त हुआ है जो कि मेरे डेटाबेस में नहीं है इसलिए मुझे इसे पहले बनाना होगा। लेकिन यह भी हो सकता है कि वह स्थान किसी अन्य मैच की मेजबानी कर सकता है इसलिए एक अन्य उपभोक्ता शायद उसी समय इसे बनाने की कोशिश करेगा। इसलिए मुझे जो करना था वह अलग-अलग लेन-देन में पहले निर्भरता पैदा करना था, जिससे मुझे पता चला कि मैं डुप्लिकेट कुंजी अपवाद में इकाई प्रबंधक को रीसेट कर रहा था। मैं कहूंगा कि मैच के बगल में मौजूद सभी संस्थाओं को "साझा" के रूप में परिभाषित किया जा सकता है क्योंकि वे संभवतः अन्य उपभोक्ताओं में अन्य लेनदेन का हिस्सा हो सकते हैं। कुछ ऐसा है जो "साझा" नहीं है, यह मैच ही है जो संभवतः एक ही समय में दो उपभोक्ताओं द्वारा नहीं बनाया जाएगा।
इस सब के कारण एक और मुद्दा भी बन गया। यदि आप इकाई प्रबंधक को रीसेट करते हैं, तो रीसेट करने से पहले आपके द्वारा पुनर्प्राप्त सभी ऑब्जेक्ट पूरी तरह से नए हैं। तो सिद्धांत उन पर एक अद्यतन चलाने की कोशिश नहीं करेंगे, लेकिन एक INSERT ! इसलिए सुनिश्चित करें कि आप अपने सभी निर्भरता को तार्किक रूप से सही लेनदेन में बनाते हैं और फिर लक्ष्य इकाई में स्थापित करने से पहले अपनी सभी वस्तुओं को डेटाबेस से वापस प्राप्त करते हैं। एक उदाहरण के रूप में निम्नलिखित कोड पर विचार करें:
$group = $this->createGroupIfDoesNotExist($groupData);
$match->setGroup($group);
$venue = $this->createVenueIfDoesNotExist($venueData);
$round = $this->createRoundIfDoesNotExist($roundData);
तो यह है कि मुझे लगता है कि यह किया जाना चाहिए।
$group = $this->createGroupIfDoesNotExist($groupData);
$venue = $this->createVenueIfDoesNotExist($venueData);
$round = $this->createRoundIfDoesNotExist($roundData);
$group = $this->getGroup($groupData);
$venue = $this->getVenue($venueData);
$round = $this->getGroup($roundData);
$match->setGroup($group);
$match->setVenue($venue);
$match->setRound($round);
$matchTeamHome = new MatchTeam();
$matchTeamHome->setMatch($match);
$matchTeamHome->setTeam($teamHome);
$matchTeamAway = new MatchTeam();
$matchTeamAway->setMatch($match);
$matchTeamAway->setTeam($teamAway);
$match->addMatchTeam($matchTeamHome);
$match->addMatchTeam($matchTeamAway);
$em->persist($match);
$em->persist($matchTeamHome);
$em->persist($matchTeamAway);
$em->flush();
मुझे उम्मीद है यह मदद करेगा :)