est-il un moyen facile d'expirer une instruction SQL de sorte qu'il échouera au lieu d'attendre (par exemple livrer un jeu de résultats vide ou un message d'erreur ou autre sinon) je peux laisser la réservation de ressources d'un travail échouer et donner une autre chance à un autre? Je cherche une option DBI que j'ai oubliée jusqu'ici; m'envoyer des SIGALRM à moi-même pour me suicider n'est pas ce que j'ai en tête (bien que je doive avoir recours à ça si je le devais).Comment temporiser un "sélectionner pour la mise à jour" dans Oracle en utilisant Perl DBI
Le code snipé est pseudo-réduit et raccourci à l'extrême, mais j'espère que vous allez attraper la dérive.
my $sql = "SELECT one, two, three FROM sometable WHERE this = ? AND that = ?";
my $sth = $self->make_handle($sql);
eval {
foreach my $this (sort keys %needed_ressources) {
# vvv This is where the idle time is spent vvv
$sth->execute($this, $that) or die("DB connection gone?!");
# ^^^ This is where the idle time is spent ^^^
my ($one, $two, $three) = $sth->fetchrow_array();
unless($one) { # undefined record set == not found
$self->{DB_HANDLE}->rollback();
die("$this not defined for $that!");
}
}
# If we haven't died so far, we can move on
foreach... #similar loop here doing the actual update statement
$self->{DB_HANDLE}->commit();
};
return(1) unless [email protected];
return(undef);
Voici les détails gores pour l'intéressé:
Dans une application qui fait numbercrunching massivement parallèle il existe un mécanisme de verrouillage mis en œuvre qui utilise ressource une table d'oracle. Chaque tâche doit verrouiller un certain nombre de ressources à lire et/ou un certain nombre de ressources à écrire, et ne peut démarrer que si tous les verrous ont été acquis avec succès. Au lieu d'attendre patiemment que les ressources soient libérées, les tâches devraient simplement échouer et être relancées plus tard par leur maître (cela réduit le nombre de transactions ouvertes, tout en améliorant les performances en ayant plus de tâches autour de celles-ci). Bien sûr, avant de mettre à jour la table, chaque ligne est réservée à l'aide d'une instruction "SELECT ... FOR UPDATE", de sorte qu'Oracle utilise le verrouillage de ligne et que des transactions simultanées peuvent se produire sur la table. Afin de réduire davantage les conditions de course possibles et les blocages, tous les travaux sélectionnent d'abord leurs lignes de ressources, puis les verrouillent en utilisant la même commande avant d'effectuer la mise à jour.
À partir de la mise en œuvre actuelle, cela fonctionne très bien dans plus des cas. Mais, parce que le "Select for update" bloque jusqu'à ce qu'Oracle accorde effectivement le verrou de ligne, il peut toujours arriver qu'un travail soit inactif attendant ses ressources, et je suis après ceux-ci pour mieux utiliser la puissance de processeur disponible. C'est OK d'attendre une seconde ou deux, mais pas dix ou plus juste pour le verrouillage. Pour un verrouillage plus tard, l'attente est nécessaire bien sûr, de sorte que la définition de la connexion DB entière pour accepter uniquement les résultats immédiats ne fonctionnera pas.
Je suis toujours reconnaissant pour RTFM réponses aussi longtemps qu'ils pointent vers l'emplacement dans le M que je TF ont R ;-))
Merci beaucoup à l'avance
Olfan
Qu'entendez-vous par "se suicider"? Vous pouvez configurer votre gestionnaire SIGALRM pour qu'il fasse ce que vous voulez. Essayez-vous simplement d'éviter complètement les signaux? – jiggy
J'essaie d'avoir seulement le processus maître pour gérer les signaux. Peut-être que Perl peut le gérer, mais ma structure cérébrale interne n'est pas prête à avoir différentes manipulations de signaux dans les processus père et enfant. – Olfan