2016-06-11 3 views
1

Ich habe ein seltsames Verhalten in go's Datenbank/sql-Paket festgestellt, mit dem PostgreSQL-Treiber von lib/pq. Grundsätzlich, wenn ich eine Datenbankverbindung für eine Abfrage verwende, während ich eine Transaktion auf derselben Verbindung erstelle, gehe ich in eine tote Sperre und das Programm blockiert (ich muss den Datenbankserver manuell neu starten, damit er wieder funktioniert). Im folgenden Beispielcode würde ich bei der SELECT-Anweisung steckenbleiben und die zweite insert-Anweisung würde nie ausgeführt werden (während, wenn ich die Abfrage entferne, wird der Code normal ausgeführt).Dead Lock in Golang-Datenbank/sql

tx, _ := connection.Begin() 
tx.Exec(insert_statement) 
rows, _ := connection.Query(select_statement) 
rows.Close() 
tx.Exec(insert_statement_2) 
tx.Commit() 

Ist das normal? Soll ich jedes Mal eine neue Datenbankverbindung erstellen, wenn ich Transaktionen verwenden möchte?

Antwort

0

Die connection.Query-Funktion wird nicht in derselben Sitzung wie die tx.XXX-Funktionen ausgeführt, wenn select_statement zufällig auf alles verweist, auf das von insert_statement geschrieben wurde, das Sie möglicherweise blockieren würden.

versuchen Sie tx.Query (select_statement) um zu sehen, ob dieser blockiert.

+0

Ja, tx.Query() würde funktionieren, aber ich kann das nicht immer kontrollieren. Die Transaktion tx wird verwendet, um einige Aktualisierungen der Datenbank durch den Administrator vorzunehmen, während die Abfrage von Benutzern aufgerufen wird, die die Website besuchen. Also könnten die zwei Dinge zur selben Zeit passieren und ich würde es vorziehen, wenn es meine Datenbank nicht herunterfahren würde! – splinter123

+0

Ich würde nur erwarten, dass dies zu einem Deadlock führt, wenn es in derselben Goroutine ausgeführt wird. Sie bekommen dieses Problem, wenn verschiedene Routinen die verschiedenen Dinge ausführen? Auch postgresql SELECT-Anweisungen sperren nicht, es sei denn, Sie tun "für Update", machen Sie das? –

+0

Ich habe es nicht auf verschiedenen goroutines getestet, ich habe versucht, naiv ein gleichzeitiges Verhalten zu replizieren, indem ich verschiedene Dinge auf dem gleichen Thread mache, aber wahrscheinlich ist es nicht der gute Weg zu gehen. Die select-Anweisung ist nur eine einfache "select * from mytable", wobei dieselbe "mytable" durch die vorherige Einfügung modifiziert wurde. – splinter123