2010-01-01 9 views
17

मैं पाइथन में एक छोटा डेटाबेस एडाप्टर लिख रहा हूं, ज्यादातर मज़ेदार के लिए। मैं कोड को उस स्थिति से सुदृढ़ रूप से पुनर्प्राप्त करने की कोशिश कर रहा हूं जहां MySQL कनेक्शन "चला जाता है," उर्फ ​​wait_timeout पार हो गया है। मैंने wait_timeout को 10 पर सेट किया है, इसलिए मैं इसे आजमा सकता हूं।अनुग्रहपूर्वक "MySQL दूर चला गया है"

यहाँ मेरी कोड है:

def select(self, query, params=[]): 
     try: 
      self.cursor = self.cxn.cursor() 
      self.cursor.execute(query, params) 
     except MySQLdb.OperationalError, e: 
      if e[0] == 2006: 
       print "We caught the exception properly!" 
       print self.cxn 
       self.cxn.close() 
       self.cxn = self.db._get_cxn() 
       self.cursor = self.cxn.cursor() 
       self.cursor.execute(query, params) 
       print self.cxn 

     return self.cursor.fetchall() 

अगला मैं दस सेकंड प्रतीक्षा करें और एक अनुरोध बनाने के लिए प्रयास करें। चेरीपी इस तरह दिखता है:

[31/Dec/2009:20:47:29] ENGINE Bus STARTING 
[31/Dec/2009:20:47:29] ENGINE Starting database pool... 
[31/Dec/2009:20:47:29] ENGINE POOL Connecting to MySQL... 
[31/Dec/2009:20:47:29] ENGINE POOL Connecting to MySQL... 
[31/Dec/2009:20:47:29] ENGINE POOL Connecting to MySQL... 
[31/Dec/2009:20:47:29] ENGINE POOL Connecting to MySQL... 
[31/Dec/2009:20:47:29] ENGINE POOL Connecting to MySQL... 
[31/Dec/2009:20:47:29] ENGINE Started monitor thread '_TimeoutMonitor'. 
[31/Dec/2009:20:47:29] ENGINE Started monitor thread 'Autoreloader'. 
[31/Dec/2009:20:47:30] ENGINE Serving on 0.0.0.0:8888 
[31/Dec/2009:20:47:30] ENGINE Bus STARTED 
We caught the exception properly! <====================================== Aaarg! 
<_mysql.connection open to 'localhost' at 1ee22b0> 
[31/Dec/2009:20:48:25] HTTP Traceback (most recent call last): 
    File "/usr/local/lib/python2.6/dist-packages/CherryPy-3.1.2-py2.6.egg/cherrypy/_cprequest.py", line 606, in respond 
cherrypy.response.body = self.handler() 
    File "/usr/local/lib/python2.6/dist-packages/CherryPy-3.1.2-py2.6.egg/cherrypy/_cpdispatch.py", line 25, in __call__ 
    return self.callable(*self.args, **self.kwargs) 
    File "adp.py", line 69, in reports 
    page.sources = sql.GetSources() 
    File "/home/swoods/dev/adp/sql.py", line 45, in __call__ 
    return getattr(self.formatter.cxn, parsefn)(sql, sql_vars) 
    File "/home/swoods/dev/adp/database.py", line 96, in select 
    self.cursor.execute(query, params) 
    File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 166, in execute 
    self.errorhandler(self, exc, value) 
    File "/usr/lib/pymodules/python2.6/MySQLdb/connections.py", line 35, in defaulterrorhandler 
    raise errorclass, errorvalue 
OperationalError: (2006, 'MySQL server has gone away') 

[31/Dec/2009:20:48:25] HTTP 
Request Headers: 
    COOKIE: session_id=e14f63acc306b26f14d966e606612642af2dd423 
    HOST: localhost:8888 
    CACHE-CONTROL: max-age=0 
    ACCEPT: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 
    ACCEPT-CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.3 
    USER-AGENT: Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/532.5 (KHTML, like  Gecko) Chrome/4.0.249.43 Safari/532.5 
    CONNECTION: keep-alive 
    Remote-Addr: 127.0.0.1 
    ACCEPT-LANGUAGE: en-US,en;q=0.8 
    ACCEPT-ENCODING: gzip,deflate 
127.0.0.1 - - [31/Dec/2009:20:48:25] "GET /reports/1 HTTP/1.1" 500 1770 "" "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.43 Safari/532.5" 

यह काम क्यों नहीं करता ?? मैं अपवाद को स्पष्ट रूप से पकड़ता हूं, कनेक्शन और कर्सर दोनों को पुन: उत्पन्न करता हूं, लेकिन यह अभी भी काम नहीं करता है। क्या यह संबंधित है कि MySQLdb कनेक्शन कैसे प्राप्त करता है?

उत्तर

12

कोड से नहीं देख सकता है, लेकिन मेरा अनुमान है कि db._get_cxn() विधि किसी प्रकार का कनेक्शन पूलिंग कर रही है और एक नया बनाने के बजाय मौजूदा कनेक्शन ऑब्जेक्ट को वापस कर रही है। मौजूदा बेकार कनेक्शन को फ्लश करने के लिए db पर कोई कॉल नहीं है? (और क्या आप वास्तव में एक आंतरिक _ -prefixed विधि बुला रहे हैं?)

MySQL has gone away को रोकने के लिए मैं आमतौर पर आखिरी बार कनेक्शन के साथ एक टाइमस्टैम्प रखना पसंद करता हूं। फिर इसे फिर से उपयोग करने की कोशिश करने से पहले मैं टाइमस्टैम्प को देखता हूं और कनेक्शन को बंद/बंद कर देता हूं अगर इसे कुछ घंटों पहले इस्तेमाल किया गया था। यह प्रत्येक संभावित क्वेरी को try...except OperationalError...try again से लपेटता है।

+0

ठीक है आप दोनों खातों पर हैं। यह बात कई अलग-अलग दिशाओं में चली गई है। मैंने वास्तव में अनुच्छेद 2 से सुझाव लागू किया, और यह चीजों को करने का मेरा पसंदीदा तरीका है। मैंने पैराग्राफ में सुझाए गए बग को ठीक करने के लिए कोड को फिर से लिखा है (बग बिल्कुल ठीक था ... मैं अपने खुद के रिफैक्टरिंग का शिकार हूं)। आपकी मदद के लिए बहुत बहुत धन्यवाद। नया साल मुबारक हो! –

+5

@ सेनवुड - क्या आप अपना सही कोड साझा कर सकते हैं? मैं वही समस्या से पीड़ित हूं जैसा आपने किया था ... – Jonathan

+0

@ सेनवुड क्या आपने कोड साझा करने के बारे में कोई विचार दिया है? ऐसा लगता है कि मैं भी एक ही त्रुटि से पीड़ित हूं। मैंने अपने शुरुआती डेटाबेस कनेक्शन के चारों ओर 3 प्रयासों के लिए थोड़ी देर लूप लगाई है, लेकिन जैसा कि बॉबन्स ने उल्लेख किया है, मैंने प्रत्येक प्रश्न को छोड़कर कोशिश की है। मैंने हर एक प्रश्न को छोड़कर कोशिश की है, लेकिन मैं वास्तव में सर्वर अपवाद को पकड़ नहीं रहा हूं। –

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