2015-10-20 6 views
5

Ich versuche, eine mysql-Verbindung zu einem Thread in Python zu übergeben. Wenn ich die mysql innerhalb der Worker-Klasse initialisiere, gibt es keinen Fehler.Erhalten einer beschädigten Pipe beim Übergeben einer MySQL-Verbindung an einen Python-Thread

Allerdings könnte es für die Verbindung teuer sein, also habe ich versucht, nur die mysql-Verbindung von der Anruferfunktion übergeben (siehe Code unten). Aber das wirft diesen Fehler fort:

(2006, "MySQL server has gone away (BrokenPipeError(32, 'Broken pipe'))

Irgendeine Idee warum? Ich denke, die wegen der Art, wie wir

def worker(db): 
""" Distributes the workload for a thread 
""" 
while True: 
    item = queue_handler.get() 
    perform_insert(item, db) 
    queue_handler.task_done() 

def insert_bulk(params): 
""" Handles the insert 
""" 
    cntr = 0 
    res = [] 
    cannot_read = [] 
    (data, cms, report_id) = params 

    db = nmi_mysql.DB(CONFIG['earnings_db'], True) 

    for i in range(10): 
     thrd = threading.Thread(target=worker, args=(db,)) 
     thrd.deamon = True 
     thrd.start() 

    for row in data: 
     split_files = row.split(',') 

     if len(split_files) != 34: 
      cannot_read.append(split_files) 
      continue 

     now = datetime.datetime.now() 

     res.append(<some data to insert>) 

     if len(res) == 750 or cntr == len(data): 
      queue_handler.put([res, cms, report_id]) 
      res = [] 

     cntr += 1 

    queue_handler.join() 

    db.close() 

    return [len(res), cms] 

UPDATE

Statt die MySQL-Verbindung des Leitens des MySQL-Verbindung passieren, haben wir einen Verbindungspool und diesen Pool in den Threads verwenden. Auf diese Weise erhalten wir nur eine Verbindung vom Pool auf der Thread-Ebene.

+0

Normalerweise werden Datenbankverbindungen nicht zwischen verschiedenen Client-Threads verwendet: Sie sind nicht _thread-safe_. Wenn Ihnen niemand eine bessere Antwort bietet, würde ich Ihnen empfehlen, jede Verbindung im selben Thread zu bearbeiten: Öffnen, Verwenden und Schließen. –

+0

@LittleSanti verwendeten wir stattdessen einen Verbindungspool. Funktioniert wirklich gut. – Ninz

+0

Es ist in Ordnung, einen Pool zu verwenden, während Sie jede Verbindung vollständig innerhalb desselben Threads behandeln: Verbindung herstellen, verwenden, freigeben. Der Grund ist immer noch der gleiche: Verbindungen sind in der Regel nicht Thread-sicher. –

Antwort

2

Datenbankverbindungen sind nicht Thread-sicher, daher sollten Sie sie nicht von einem Thread zum anderen weitergeben. Ein Verbindungspool hält offene Verbindungen zwischen Anforderungen aufrecht, sodass es schneller ist, eine Verbindung vom Pool zu erhalten, sie für eine Abfrage zu verwenden und sie dann freizugeben.

Diese related answer enthält einige nützliche Links zur Threadsicherheit von Datenbankverbindungen.

+0

Meine Antwort ist meistens eine Zusammenfassung der Kommentare. Ich habe es gerade gepostet, damit diese Frage aus der Liste der unbeantworteten Fragen entfernt wird. –

Verwandte Themen