2010-01-01 34 views
17

Tôi đang viết một bộ điều hợp cơ sở dữ liệu nhỏ bằng Python, chủ yếu là để giải trí. Tôi đang cố gắng để có được mã để phục hồi một cách duyên dáng từ một tình huống mà kết nối MySQL "biến mất", còn gọi là wait_timeout bị vượt quá. Tôi đã đặt wait_timeout tại 10 để tôi có thể thử điều này.Xử lý duyên dáng "MySQL đã biến mất"

Dưới đây là mã của tôi:

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() 

Tiếp theo, tôi chờ đợi mười giây và cố gắng để thực hiện một yêu cầu. Đây là những gì CherryPy trông giống như:

[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" 

Tại sao nó không hoạt động? Tôi nắm bắt rõ ràng ngoại lệ, tạo lại cả kết nối và con trỏ, nhưng nó vẫn không hoạt động. Là nó liên quan đến cách MySQLdb được các kết nối?

Trả lời

12

Không thể nhìn thấy từ mã, nhưng tôi đoán là phương pháp db._get_cxn() đang thực hiện một số loại kết nối tổng hợp và trả về đối tượng kết nối hiện có thay vì tạo đối tượng mới. Không có cuộc gọi nào bạn có thể thực hiện trên db để xóa kết nối vô dụng hiện có? (Và bạn có thực sự đang gọi phương thức nội bộ _ -prefixed không?)

Để ngăn chặn MySQL has gone away Tôi thường muốn giữ dấu thời gian với kết nối lần cuối cùng tôi sử dụng nó. Sau đó, trước khi thử sử dụng lại, tôi nhìn vào dấu thời gian và đóng/hủy kết nối nếu nó được sử dụng lần cuối hơn vài giờ trước. Điều này tiết kiệm gói mỗi truy vấn có thể với một try...except OperationalError...try again.

+0

Ngay khi bạn ở trên cả hai tài khoản. Điều này đã đi theo nhiều hướng khác nhau. Tôi thực sự đã thực hiện đề xuất từ ​​đoạn 2, và đó là cách làm việc ưa thích của tôi. Tôi đã viết lại mã để sửa lỗi bạn đề xuất trong đoạn một (lỗi chính xác là ... Tôi là nạn nhân của việc tái cấu trúc của chính tôi). Cảm ơn rất nhiều sự giúp đỡ của bạn. Chúc mừng năm mới! –

+5

@SeanWoods - Bạn có thể chia sẻ mã đã sửa của mình không? Tôi đang gặp vấn đề tương tự như bạn đã làm ... – Jonathan

+0

@SeanWoods Bạn đã đưa ra bất kỳ suy nghĩ nào về việc chia sẻ mã? Có vẻ như tôi cũng bị lỗi tương tự. Tôi đã đặt một vòng lặp trong khi xung quanh kết nối cơ sở dữ liệu ban đầu của tôi cho 3 lần nhưng như bobince đã đề cập tôi đã đặt thử ngoại trừ trong mỗi truy vấn duy nhất. Tôi đã thử ngoại trừ mỗi truy vấn đơn nhưng tôi không thực sự bắt máy chủ đi ngoại lệ. –

Các vấn đề liên quan