2012-09-11 6 views
6

Ist es in Ordnung, eine einzelne MySQLdb-Verbindung für mehrere Transaktionen zu verwenden, ohne die Verbindung zwischen ihnen zu schließen? Mit anderen Worten, etwas in der Art:MySQLdb mit mehreren Transaktionen pro Verbindung

conn = MySQLdb.connect(host="1.2.3.4", port=1234, user="root", passwd="x", db="test") 

for i in range(10): 
    try: 
     cur = conn.cursor() 
     query = "DELETE FROM SomeTable WHERE ID = %d" % i 
     cur.execute(query) 
     cur.close() 
     conn.commit() 

    except Exception: 
     conn.rollback() 

conn.close() 

Es scheint zu funktionieren, okay, aber ich wollte nur doppelt überprüfen.

+0

Schade, dass Sie Ihren Fehler nicht verlassen haben. Ich war wirklich verwirrt, bevor ich die Revisionen gelesen habe, weil ich nicht gesehen habe, worüber das Missverständnis Martijn Pieters sprach. –

Antwort

15

Ich denke, es gibt ein Missverständnis darüber, was eine Transaktion hier ausmacht.

Ihr Beispiel öffnet eine Verbindung und führt dann eine Transaktion darauf aus. Sie führen in dieser Transaktion mehrere SQL-Anweisungen aus, aber Sie schließen sie nach dem Commit vollständig. Natürlich ist das mehr als in Ordnung.

mehrere Ausführen Transaktionen (im Gegensatz zu nur SQL-Anweisungen), sieht wie folgt aus:

conn = MySQLdb.connect(host="1.2.3.4", port=1234, user="root", passwd="x", db="test") 

for j in range(10): 
    try: 
     for i in range(10): 
      cur = conn.cursor() 
      query = "DELETE FROM SomeTable WHERE ID = %d" % i 
      cur.execute(query) 
      cur.close() 
     conn.commit() 
    except Exception: 
     conn.rollback() 

conn.close() 

Der obige Code verpflichtet 10 Transaktionen, die jeweils aus 10 Einzelaussagen löschen.

Und ja, Sie sollten in der Lage sein, die offene Verbindung für diese ohne Probleme wieder zu verwenden, solange Sie diese Verbindung zwischen Threads nicht teilen.

Zum Beispiel verwendet SQLAlchemy Verbindungen erneut, indem sie diese zusammenfasst und offene Verbindungen nach Bedarf an die Anwendung ausgibt. Neue Transaktionen und neue Anweisungen werden für diese Verbindungen während der gesamten Lebensdauer einer Anwendung ausgeführt, ohne dass sie geschlossen werden müssen, bis die Anwendung heruntergefahren wird.

+0

Ja, du hast Recht. Ich habe mein Beispiel vermasselt, während ich es verwässerte, um es zu veröffentlichen. Ich werde das reparieren. – d512

+0

Was wäre das Problem beim Teilen von Verbindungen zwischen Threads in meinem Szenario? – d512

+2

@ user1334007: Aus der [MySQLdb-Dokumentation] (http://mysql-python.sourceforge.net/MySQLdb.html): * "Wenn Sie zwei Threads gleichzeitig eine Verbindung verwenden lassen, wird die MySQL-Client-Bibliothek wahrscheinlich verkracht und stirbt. Du wurdest gewarnt."*. –

0

Es wäre besser, zuerst eine Abfragezeichenfolge zu erstellen und dann diese einzelne MySQL-Anweisung auszuführen. Zum Beispiel:

query = "DELETE FROM table_name WHERE id IN (" 
for i in range(10): 
    query = query + "'" + str(i) + "', " 
query = query[:-2] + ')' 

cur = conn.cursor() 
cur.execute(query) 
+0

Das ist effizienter, aber es gibt Gründe, warum ich es nicht so mache. – d512

+0

Aussteigen, nur überprüfen. –