Perl DBIx :: Klassentransaktionen mit fehlendem Commit
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
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 herstellenauto_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.
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.