Perl DBIx :: Klassentransaktionen mit fehlendem Commit

Sep 29 2020

Ich habe Probleme mit einem inkonsistenten Verhalten des Perl DBIx :: Class-Moduls. Ich habe eine einfache reine Perl-Klasse geschrieben, die das Klassenmitglied 'Schema' definiert. Dies ist nur eine Referenz auf ein vorinitialisiertes / verbundenes DBIx :: Class :: Schema-Objekt und eine Methode zum Hinzufügen einiger Daten zur Datenbank:

sub new {
    my $class = shift; my $params;
    if(1 == scalar @_ && 'HASH' eq ref($_[0])) { $params = shift;
    } else {
        my %params = @_;
        $params = \%params; } my $self = {
        schema => $params->{schema} }; bless $self, $class; return $self;
}


sub addToQueue {
    my $self = shift; my $params;
    if(1 == scalar @_ && 'HASH' eq ref($_[0])) { $params = shift;
    } else {
        my %params = @_;
        $params = \%params; } #some parameter constraints checks .... $self->{schema}->txn_do(sub {
        $self->{schema}->resultset('SOME_QUEUE')->create($params);
    });

    # this row is necessary if this method is called from programs, which uses moose
    $self->{schema}->txn_commit();
 
    return;
}

Wenn ich die Methode addToQueue aus einem Perl-Programm (verwendet Moose) aufrufe, muss ich die Codezeile hinzufügen

self->{schema}->txn_commit();

um den DB-Commit-Befehl wirklich auszulösen. Wenn ich die Methode von einem anderen Perl-Programm aus aufrufe (verwendet Moose nicht), schlägt der Code mit der folgenden Meldung fehl:

Verwendung des nicht initialisierten Werts $ msg in Substitution (s ///) unter /usr/local/share/perl/5.20.2/DBIx/Class/Exception.pm Zeile 58. Verwendung des nicht initialisierten Werts $ msg in Verkettung (.) Oder Zeichenfolge in /usr/local/share/perl/5.20.2/DBIx/Class/Exception.pm Zeile 68. DBIx :: Class :: Storage :: txn_commit (): Verweigert das Festschreiben ohne gestartete Transaktion

Wenn ich den doppelten Commit-Befehl entferne, funktioniert er für das Nicht-Moose-Programm, aber das Moose using-Programm lässt das Commit aus und der erstellte Eintrag wird nicht in die Datenbank geschrieben.

Kennt jemand dieses Problem?

Antworten

1 ikegami Sep 28 2020 at 23:39

Aus der Dokumentation fürtxn_do ,

WARNUNG: Wenn Sie mit AutoCommit => 0der Transaktion verbunden sind, gilt dies als verschachtelt, und Sie müssen weiterhin "txn_commit" aufrufen, um Ihre Änderungen gegebenenfalls zu schreiben. Sie möchten auch eine Verbindung herstellen auto_savepoint => 1, damit ein teilweises Rollback funktioniert, wenn der Speichertreiber für Ihre Datenbank dies unterstützt.

Es AutoCommit => 1wird empfohlen, eine Verbindung mit herzustellen.

Ich vermute, Sie verwenden, AutoCommit => 0wenn Sie das Extra benötigen txn_commit.

AlexanderHartmaier Sep 30 2020 at 03:23

Die kurze Antwort lautet: Sie schreiben die Transaktion zweimal fest. txn_doWird beim Verlassen des Blocks automatisch festgeschrieben, wenn keine Ausnahme ausgelöst wird. Bitte posten Sie ein Codebeispiel, das Moose und das Protokoll von DBIC_TRACE = 1 lädt und zeigt, dass kein Commit ausgelöst wird.