ढांचे के बारे में जानने का कोई तरीका नहीं है कि आपने लेनदेन शुरू किया है या नहीं। आप $db->query('START TRANSACTION')
का भी उपयोग कर सकते हैं, जिसे ढांचे के बारे में पता नहीं चलेगा क्योंकि यह आपके द्वारा निष्पादित SQL कथन का विश्लेषण नहीं करता है।
बिंदु यह है कि यह ट्रैक करने के लिए एक आवेदन ज़िम्मेदारी है कि आपने लेनदेन शुरू किया है या नहीं। ऐसा कुछ नहीं है जो ढांचा कर सकता है।
मुझे पता है कि कुछ ढांचे इसे करने का प्रयास करते हैं, और कॉकैमामी चीजें करते हैं जैसे कि आप लेन-देन शुरू करने के कितनी बार गिनती करते हैं, केवल तभी हल करते हैं जब आप प्रतिबद्धता करते हैं या कई बार मेलबैक करते हैं। लेकिन यह पूरी तरह से फर्जी है क्योंकि आपके कार्यों में से कोई भी यह नहीं जान सकता कि प्रतिबद्ध या रोलबैक वास्तव में ऐसा करेगा, या यदि वे घोंसले की एक और परत में हैं।
(आप बता सकते हैं कि मैं इस चर्चा कई बार मिला है :-)
संपादित करें:Propel एक PHP डेटाबेस का उपयोग पुस्तकालय "आंतरिक लेन-देन" जो ऐसा नहीं करता अवधारणा का समर्थन करता है जब आप इसे बताते हैं तो प्रतिबद्ध करें। एक लेनदेन शुरू करने से केवल एक काउंटर बढ़ता है, और प्रतिबद्ध/रोलबैक काउंटर को कम करता है। नीचे एक मेलिंग सूची थ्रेड से एक अंश है जहां मैं कुछ परिदृश्यों का वर्णन करता हूं जहां यह विफल रहता है।
इसकी तरह या नहीं, लेनदेन "वैश्विक" हैं और वे ऑब्जेक्ट उन्मुख encapsulation का पालन नहीं करते हैं।
समस्या परिदृश्य # 1
मैं commit()
फोन, मेरे परिवर्तन के लिए प्रतिबद्ध हैं? अगर मैं "आंतरिक लेनदेन" के अंदर दौड़ रहा हूं तो वे नहीं हैं। बाहरी लेनदेन का प्रबंधन करने वाला कोड वापस रोल करना चुन सकता है, और मेरे परिवर्तन या ज्ञान के बिना मेरे परिवर्तनों को त्याग दिया जाएगा।
उदाहरण के लिए:
- मॉडल ए: निष्पादित कुछ परिवर्तन
- मॉडल बी:: लेन-देन (मूक कोई को-अप)
- मॉडल बी शुरू: निष्पादित कुछ बदलाव लेन-देन
- मॉडल ए शुरू
- मॉडल बी: प्रतिबद्ध (मूक नो-ऑप)
- मॉडल ए: रोलबैक (मॉडल मॉडल परिवर्तन और मॉडल बी परिवर्तन दोनों को छोड़ देता है)
- मॉडल बी: डब्ल्यूटीएफ !? मेरे परिवर्तनों के साथ क्या हुआ?
समस्या परिदृश्य # 2
एक आंतरिक लेनदेन वापस रोल, यह वैध एक बाहरी लेनदेन द्वारा किए गए परिवर्तनों को निरस्त कर सकता है। जब बाहरी कोड पर नियंत्रण वापस कर दिया जाता है, तो इसका मानना है कि इसका लेनदेन अभी भी सक्रिय है और प्रतिबद्ध होने के लिए उपलब्ध है। अपने पैच के साथ, वे commit()
पर कॉल कर सकते हैं, और चूंकि ट्रांसडेप अब 0 है, तो यह चुपचाप $transDepth
से -1 सेट करेगा और कुछ भी नहीं करने के बाद, सत्य लौटाएगा।
समस्या परिदृश्य # 3
अगर मैं commit()
या rollback()
फोन जब कोई लेन-देन सक्रिय है, यह $transDepth
-1 सेट। अगले beginTransaction()
स्तर को 0 तक बढ़ाता है, जिसका अर्थ है कि लेनदेन न तो वापस लुढ़काया जा सकता है और न ही प्रतिबद्ध किया जा सकता है। commit()
पर बाद की कॉल लेन-देन को -1 या उससे आगे तक घटाएगी, और जब तक आप फिर से स्तर को बढ़ाने के लिए एक और अनावश्यक beginTransaction()
नहीं करते हैं तब तक आप प्रतिबद्ध नहीं होंगे।
मूल रूप से, डेटाबेस लॉकिंग करने के लिए डेटाबेस को अनुमति दिए बिना एप्लिकेशन तर्क में लेनदेन प्रबंधित करने का प्रयास करना एक विनाशकारी विचार है। यदि आपके पास एक आवेदन अनुरोध में स्पष्ट लेनदेन नियंत्रण का उपयोग करने के लिए दो मॉडल की आवश्यकता है, तो आपको प्रत्येक मॉडल के लिए दो डीबी कनेक्शन खोलना होगा। फिर प्रत्येक मॉडल का अपना सक्रिय लेनदेन हो सकता है, जिसे एक दूसरे से स्वतंत्र रूप से प्रतिबद्ध या लुढ़काया जा सकता है।
(http://www.nabble.com/Zend-Framework-Db-Table-ORM-td19691776.html देखें)
लगता है कि इस मुद्दे को उनके नजर में खो गया ... :( – xelurg
सभी जेडएफ मुद्दों कहते हैं कि "अगले नाबालिग रिलीज में तय" जब तक वे वास्तव में तय कर रहे हैं। मुझे आशा है कि वे कहते हैं कि करने के लिए एक अच्छा कारण था, क्योंकि, यह बहुत भ्रामक है और बहुत से लोगों के लिए भ्रम पैदा करता है। –
mysql क्लाइंट 'SELECT @@ autocommit के माध्यम से मेरे परीक्षण में; अभी भी लेनदेन के दौरान 1 लौटाता है। – ColinM