2010-09-10 5 views
2

J'utilise cette approche. S'il y a une erreur dans le sql, la restauration ne se produit que pour le premier identifiant du groupe d'actifs. Le reste des identifiants est ignoré. Est-ce que je le fais de la bonne façon?perl dbi rollback ne fonctionne pas

my $sql = "sql batch that update and insert depending on the condition"; 
$dbh->{RaiseError} = 1; 
$dbh->{PrintError} = 0; 
$dbh->{AutoCommit} = 0; 

my $sth = $dbh->prepare($sql); 
my @error =(); 
my $num = 0; 
foreach my $id (@asset_group) { 
next if ($id eq ''); 
eval { 
    $sth->bind_param(1, $id); 
    $sth->bind_param(2, $vars{'other_id'}); 
    $sth->execute(); 

}; 
if ([email protected]) { 
    $dbh->rollback(); 
    push @error, [email protected] 
} else { 
    $dbh->commit(); 
} 
} 
+1

Que voulez-vous dire "le reste des ID sont ignorés?" – cam

+0

Vous pouvez définir explicitement la transaction avec 'BEGIN', puis' END/COMMIT/ROLLBACK', même si vous désactivez AutoCommit. Avec quel SGBD travaillez-vous? – vol7ron

+0

Attention, la validation peut échouer aussi. – bohica

Répondre

7

En fonction de la base de données, vous devrez peut-être émettre un begin work avant de commencer à changer les choses. J'ai l'impression de me souvenir qu'Informix en a besoin. En outre, il semble que vous générez une validation ou une annulation après chaque exécution. Une fois que vous vous êtes engagé, vous ne pouvez pas revenir en arrière. Normalement, on dit quelque chose comme

$dbh->begin_work; 
eval { 
    for my $id (@asset_group) { 
     next if ($id eq ''); 
     $sth->execute($id, $vars{other_id}); 
    } 
    1; #if it doesn't die then this will force it to return true 
} or do { 
    my $error = DBI->errstr; 
    $dbh->rollback(); 
    die "could not insert rows: $error\n" 
}; 
$dbh->commit(); 

Remarque que je ne l'utilise [email protected]. [email protected] est untrustworthy.

+0

Vous ne devriez pas avoir besoin d'appeler 'begin_work'. Il existe principalement pour vous permettre d'utiliser une transaction pour un groupe d'actions particulier même si vous avez activé AutoCommit. Avec AutoCommit désactivé (comme c'est ici), tout ce qu'il fait est mourir si la base de données ne supporte pas les transactions. Mais le reste de votre réponse est un bon conseil. – cjm

+0

Merci à tous. ça a marché. – alp

+1

@alp, alors vous devez marquer la réponse comme acceptée en cliquant sur la coche près de son score. – cjm

Questions connexes