2012-03-30 35 views
11

मुझे अपने क्लाइंट डिस्कनेक्ट होने के तुरंत बाद MySQL सर्वर को रोलबैक लेनदेन करने की आवश्यकता है, क्योंकि प्रत्येक क्लाइंट समवर्ती रूप से काम करता है। समस्या इस तरह reproduced किया जा सकता है

ग्राहक एक पर (एक InnoDB तालिका प्रकार का उपयोग):खोए/डिस्कनेक्ट किए गए कनेक्शन के साथ लेनदेन पर MySQL रोलबैक

START TRANSACTION; 
SELECT MAX(ID) FROM tblone FOR UPDATE; 
#... then disconnect your connection to the server 

ग्राहक बी पर:

START TRANSACTION; 
SELECT MAX(ID) FROM tblone FOR UPDATE; 
#... lock wait time out will occur here 

मैं निर्धारित किया था innodb_rollback_on_timeout तरह MySQL के सर्वर विकल्प का उपयोग दोनों क्लाइंट पर mysql का क्लाइंट mysql --skip-reconnect। मैंने नेटवर्क पर एक सर्वर और दो क्लाइंट का उपयोग करके इसे आजमाया। मैंने SELECT ... FOR UPDATE; लाइन के बाद नेटवर्क को भौतिक रूप से (केबल को अनप्लग करें) डिस्कनेक्ट कर दिया। मुझे अन्य क्लाइंट को लेनदेन पर tblone का उपयोग करने में सक्षम होना चाहिए (इसे लॉक करें, इसे अपडेट करें), और इसके लिए मुझे लगता है कि क्लाइंट ए डिस्कनेक्ट होने के बाद सर्वर को क्लाइंट ए के लेनदेन को रोलबैक करना चाहिए।

+0

दिलचस्प सवाल। मैंने सोचा कि यह स्वचालित है! तो हमें 'innodb_rollback_on_disconnect' जैसी कुछ चाहिए .. यह बहुत अच्छा होगा और मैं कहूंगा, यह डिफ़ॉल्ट होना चाहिए! यह mysql के लिए उचित परिवर्तन अनुरोध होगा। – TMS

उत्तर

10

जब आप किसी क्लाइंट को भौतिक रूप से डिस्कनेक्ट कर रहे हैं तो आप एक सामान्य डिस्कनेक्ट नहीं भेज रहे हैं (जो रोलबैक का कारण बनता है) और MySQL प्रोटोकॉल बहुत चिपचिपा नहीं है, इसलिए सर्वर कभी नहीं जानता कि क्लाइंट वहां नहीं है। मुझे लगता है कि यह अन्य डेटाबेस सिस्टम की तुलना में प्रोटोकॉल में एक दोष है जहां क्लाइंट और सर्वर आंतरिक रूप से और अधिक बात करते हैं।

वैसे भी। दो चर हैं जिन्हें आप बदल सकते हैं। वे मूल रूप से वही करते हैं लेकिन विभिन्न ग्राहकों के लिए।

पहला wait_timeout है और इसका उपयोग जावा या php जैसे अनुप्रयोग क्लाइंट द्वारा किया जाता है।

अन्य interactive_timeout है और यह (अपने परीक्षण के रूप में)

दोनों ही मामलों में सर्वर सेकंड की संख्या के बाद कनेक्शन को मारता है और ऐसा करते हुए सभी लेनदेन और विज्ञप्ति सभी रोलबैक करने के लिए mysql ग्राहक द्वारा प्रयोग किया जाता है ताले।

+0

आपके उत्तर के लिए धन्यवाद, और मैंने दोनों विकल्पों का उपयोग करने का प्रयास किया है, और उन्हें 60 सेकंड (प्रयोग के लिए) पर सेट किया है, लेकिन एक और समस्या उत्पन्न होती है। 60 सेकंड निष्क्रियता (निष्क्रिय) के बाद कनेक्शन स्वचालित रूप से बंद हो गया, और अगली क्वेरी ने एक त्रुटि उत्पन्न की (सर्वर चला गया है) और फिर स्वचालित रूप से फिर से कनेक्ट हो जाता है। क्या कनेक्शन सुनिश्चित करने के लिए मुझे हर 59 के प्रश्न पूछने के लिए कुछ कोड करने की आवश्यकता है? क्या कोई और तरीका है? एक लंबी पूछताछ है कि 60 से अधिक समय लेता है प्रक्रिया के बीच में डिस्कनेक्ट हो जाएगा? – qsoft

+0

क्योंकि लेनदेन में मुझे केवल इस व्यवहार की आवश्यकता है, क्या मैं लेनदेन से ठीक पहले 'SET SESSION wait_timeout = 60' जैसे कुछ कर सकता हूं और प्रतिबद्ध/रोलबैक के बाद इसे पुनर्स्थापित कर सकता हूं? – qsoft

+0

लेनदेन शुरू करने से पहले आपको इसे अपनी संग्रहीत प्रक्रिया में या एक अलग कथन के रूप में बदलने में सक्षम होना चाहिए। और आप निष्क्रिय कनेक्शन बंद होने के बारे में सही हैं। यह ऐसे काम करता है। हालांकि, लंबे समय तक चलने वाले प्रश्नों को "निष्क्रिय" के रूप में नहीं माना जाता है, जहां तक ​​मैंने देखा है कि सुरक्षित होना चाहिए ('चयन 1, नींद (61) दोहरी से परीक्षण करने में आसान) –

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

  • कोई संबंधित समस्या नहीं^_^