2016-08-01 36 views
1

Ich habe ein Perl-Skript, das über verschiedene Verbindungstreiber mit vielen Datenbanken verbunden ist.So trennen Sie alle Verbindungszeichenfolgen für die Datenbank

Gibt es eine Möglichkeit, ich kann eine einzige Funktion trennen trennen am Ende zu trennen, wenn es eine aktive Sitzung gibt?

Beispiel:

connection 1: $dbh->oracle; 
connection 2: $dbh->sql 

Kann ich für beide Datenbanken eine gemeinsame Trenn Zeichenfolge haben?

+3

DBI wird implizit für Sie die Verbindung trennen, wenn das Anweisungshandle den Gültigkeitsbereich verlässt. – simbabque

+0

@simbabque: Ich bekomme Fehler als: Ausgeben Rollback() wegen DESTROY ohne explizite Trennung() ..... Ich verwende separate Trennfunktion, um dies zu verhindern, aber es wäre toll, eine einzige Trennfunktion für alle zu verwenden die Saiten . – Husk01inJun

Antwort

3

Sie können das selbst implementieren, indem Sie visit_handles from DBI verwenden.

use strict; 
use warnings; 
use DBI; 

my $dbh = DBI->connect('DBI:mysql:database=test;host=localhost', 'root', 'pw'); 
my $dbh2 = DBI->connect('DBI:mysql:database=test;host=localhost', 'root', 'pw'); 

DBI->visit_handles(
    sub { 
     my ($driver_handle, $info) = @_; 

     if ($driver_handle->{Type} eq 'db') { 
      # clean up transaction or simply disconnect for each handle 
      $driver_handle->disconnect; 
     } 

     return 1; 
    } 
); 

Der Code Bezug auf visit_handles weitergegeben wird für jeden Treiber-Handle aufgerufen werden. Wenn es einen wahren Wert zurückgibt, ruft es anschließend visit_child_handles mit der gleichen Code-Referenz auf. Auf diese Weise können Sie herausfinden, welche Datenbank-Handles (db) sind und sie explizit trennen.

Wie bei Borodin states in their answer müssen Sie vor dem Trennen der Verbindung die halbfertigen Transaktionen erledigen. Diese Lösung gibt Ihnen nur eine Möglichkeit, alle Verbindungshandles von einem einzigen Ort zu erhalten.

+0

Schön. Ich wusste nichts von 'visit_handles'. Aber der explizite Aufruf von 'disconnect' erzeugt die gleiche Warnung wie die implizite Trennung, wenn Perl ein Programm zerstört, und Sie müssen 'Rollback' oder 'Commit' für jedes Handle mit einer offenen Transaktion ausführen. – Borodin

+0

@borodin hmm wahr. Ich werde bearbeiten, wenn ich zurück zu meinem Computer komme. – simbabque

+0

@Borodin war mir nicht bewusst, danke für die Informationen. Ich versuche, mich mit verschiedenen Treibern wie Oracle, Postgres und Mysql zu verbinden. Nur skeptisch, ob das funktioniert oder nicht, werde ich versuchen, wenn ich zurück zu meinem Computer komme – Husk01inJun

2

wird jede Datenbankverbindung als eine separate Datenbank könnten Sie $dbh

eindeutig ein Unterprogramm schreiben Griff dargestellt werden, die, solange die Liste der angeschlossenen Datenbanken von allen angeschlossenen Datenbank Griff trennen ist immer die gleiche

Ich bin mir nicht sicher, warum Sie auf die Verbindungszeichenfolgen fixieren. Vermutlich meinst du die DSNs (Data Source Names), die du beim Aufruf an DBI->connect benutzt hast? Sie sind Parameter einfach auf den Verbindungsvorgang und ein Datenbank-Handle kann nicht nach der Tat von seinem ursprünglichen DSN

Issuing rollback() due to DESTROY without explicit disconnect() 

identifiziert werden Dies bedeutet, dass Sie Transaktionen verwenden. Der beste Weg wäre, die Nummer rollback oder commit selbst zu wählen, um die Transaktion zu beenden. Es ist eine schlechte Idee, eine Transaktion offen zu lassen, wenn das Programm beendet wird, wie Sie auf dem Standardverhalten des Datenbanktreiber

Die documentation for DBI::disconnect sagt diese

Im Allgemeinen setzen, wenn Sie Ihre Änderungen festgeschrieben werden sollen oder Wenn Sie die Verbindung trennen, sollten Sie vor dem Trennen explizit "commit" oder "rollback" aufrufen.

Sie auch die gleiche Warnung erhalten, wenn Sie disconnect nennen, während eine Transaktion noch geöffnet ist, so ein commit oder rollback ist auf jeden Fall die richtige Methode

Es ist in Ordnung Perl Zerstörung Sequenz implcitly alle Datenbank trennen zu lassen, Handles, solange keine Transaktionen zur Zeit offen sind