2017-08-14 77 views
0

我已經用django構建了一個web服務器。Django:如何獲得與數據庫的新連接

並使用線程來運行任務,該任務保存從客戶端發送到數據庫的數據。

while True: 
     ... 
     try: 
      self.dbTarget, created = ClientMonitor.objects.get_or_create(Machine_code=own_MachC) 

      data = self.workQueue.get() #from client sent 

      self.dbTarget.setValue(data) #Custom method assigning 
      self.dbTarget.save()   #django ORM 
     except InterfaceError as ee: 
      pass 

線程是長期運行,但時間長了以後,會除外InterfaceError因爲MySQL服務器斷開連接八個小時的超時。

Especially it can not auto-reconnect to the db. Creating a new thread will be OK, but it will increase resource occupation.

所以我要重新連接數據庫時,連接在同一個線程關閉。此外,Django每個請求都會獲得全新的連接。

如何在同一個線程中獲得與數據庫的新連接? 謝謝!!!

+0

我可以調用'connection.connection.close()'來模擬'InterfaceError'。但這可能是不同的。 – Mix

回答

0

只需關閉異常處理程序中的連接即可。一個新的連接應建立您的應用程序試圖與數據庫通信的下一次:

import logging 
from django.db import connection 

try: 
    self.dbTarget, created = ClientMonitor.objects.get_or_create(Machine_code=own_MachC) 
    ... 
except InterfaceError as ee: 
    logging.warning(ee) # make sure that you log these events 
    connection.close() 
+0

如果我調用'connection.connection.close()'模擬'InterfaceError',然後'connection.close()'將重新連接連接。 – Mix

+0

太棒了!這行得通。我將mysql-server的wait_timeout從8小時改爲3秒。它會重新連接上面我的編輯。 – Mix

0

Django的使用功能close_old_connections()在每個請求的開始和結束,關閉過去他們一生的任何連接。這將檢測連接是否早於您的數據庫設置中指定的MAX_AGE,否則不可用。如果您將MAX_AGE設置爲低於數據庫的超時時間,則由於數據庫超時而不應該遇到InterfaceError

from django.db import close_old_connections 

while True: 
    try: 
     ... 
    finally: 
     close_old_connections() 
+0

我沒有設置CONN_MAX_AGE參數,因此默認值爲0.我無法測試'close_old_connections()'是否正確,因爲它花費了8小時來除了InterfaceError。 – Mix

+0

如果我調用'connection.connection.close()'來模擬'InterfaceError',然後'close_old_connections()'將會除了'django.db.utils.ProgrammingError:關閉一個關閉的連接'。 – Mix

+0

@Mix當然,在服務器端超時的連接與從客戶端明確關閉的連接不同,它們會產生不同的錯誤。服務器超時應該由'close_old_connections()'處理。 – knbk