07 juillet 2006

Expliquer les erreurs, ne pas contourner à tout prix...

Le thème technique de ce billet porte sur la gestion de l'identifiant automatique d'un fichier Hyper File (principe/panne). Le thème plus général reste le développement tête dans le guidon, vivement déconseillé dans la mesure du possible.

Les fichiers Hyper File proposent un "identifiant automatique" qui permet d'attribuer à chaque enregistrement un numéro unique. Il est incrémenté à chaque ajout, une valeur attribuée n'est jamais réutilisée même après une suppression (contrairement au numéro de l'enregistrement).

Il m'est arrivé sur un site en exploitation d'avoir une erreur de doublon sur cet identifiant automatique. Dans pareil cas, une possibilité serait de contourner immédiatement par un traitement forçant l'ajout, urgence d'une programmation tête dans le guidon, code vu aujourd'hui sur un forum. Mais une bien meilleure démarche, consiste à se documenter sur le principe de fonctionnement, afin de connaître les causes possibles.

Le principe de gestion de l'identifiant automatique est le suivant (information émanant directement du support PC SOFT) :

8<----------------------------
Le calcul du numéro d'identifiant utilise l'entête du fichier Hyper File pour stocker le dernier identifiant utilisé. L'ajout d'un nouvel enregistrement déclenche les traitements suivants :
1. Lecture du dernier identifiant ID dans l'entête
2. Calcul du nouveau identifiant, ID = ID + 1
3. Ajout du nouvel enregistrement
4. Mémorisation de l'identifiant (écriture dans l'entête).
8<----------------------------

Une erreur de doublon, provient d'un défaut d'écriture entre les étapes 3 et 4, c'est donc une panne (disque, réseau...) uniquement qui peut provoquer l'erreur, il est donc déconseillé voir dangereux de tenter un contournement par programmation. Le doublon est dans ce cas la manifestation visible de la panne, les conséquences peuvent être bien plus coûteuses en conséquences.

La solution à court terme consiste à réviser le fichier avec l'option numéro 5 du programme WDOPTIMISEUR, puis à augmenter le mode de sécurité de l'application par l'appel de la commande suivante : HSécurite(2)

Il faut ensuite diagnostiquer la panne par une expertise des installations. Dans le cas auquel j'ai été confronté, qui remonte à quelques années, il s'agissait de l'utilisation d'un poste Windows 98 qui avait servi de serveur de données malgré mes spécifications d'installation qui imposaient un Windows serveur.

10 commentaires:

Anonyme a dit…

Résoudre un problème sans trouver ou être sûr de la cause, c'est un peu limite pour du developpement. Ca ressemble un peu à du mauvais bricolage =)

Elian Lacroix a dit…

Je partage complètement votre avis. Mais dans l'urgence, on peut être amené à bruler les étapes, cela m'est arrivé. C'est pour cela que je "prêche" pour la prise de recule, sans aller jusqu'à "l'extreme programming" (http://fr.wikipedia.org/wiki/Extreme_programming).

Anonyme a dit…

Il suffirait d'inverser les 3) et 4) du code de l'entete du fichier...

Petit hs: la "prise de recul" comme vous le conseillez et très bien pour un consultant comme vous qui facturez le temps passé et les prestation tout en noyant le client sous des formulations à la "extreme programming" (ce n'est qu'un exemple). c'est vrai c'est mieux, vous reglez definitivement le problème et en plus vous vous generez du travail: impeccable. Mais croyez moi, pour un informaticien qui a les utilisateurs au c** et la boite qui perd du fric avec les heures qui passent, la prise de recul, c'est APRES le bricolage qui permet de repartir.

Je vois bien un avion se crasher et le copilote dire au pilote: "huummm, c'est du bricolage ce que vous faites cher ami, prenez donc un peu de recul"...
Donc prendre du recul ne veut pas dire bannir le "bricolage" bien au contraire: le bricolage est necessaire mais doit alerter pour une prise de recul qui se fera APRES si le problème est urgent.

Anonyme a dit…

Et pourquoi y'aurait un pb à l'écriture de l'entete du disque et pas dans le data lui meme ?
en plus une erreur disque doit logguer un event NT dans le journal système (à vérifier donc).
Je soupconnerais plus un pb d'acces concurrent à cette partie du fichier.

Elian Lacroix a dit…

A l'attention de Jean ...
Rassurez-vous, je prône la "prise de recul", tout en étant capable de commettre les pires bricolages dans l'urgence, lorsque cela est nécessaire, ou en tout cas imposé par les délais. Je partage donc complètement votre avis, tout est question d'équilibre (très fragile).

A l'attention de Patrice ...
En cas de panne matérielle malheureusement tout peut arriver. Une écriture parmi des centaines peut être perdue, et impacter l'identifiant ou tout autre chose. En local l'observateur d'événement peut effectivement donner une piste, mais s'il y a réellement une panne matérielle, son contenu peut être incertain.

Elian Lacroix a dit…

Ce billet a été repris sur un forum, mais il lui a été donné un sens totalement différent. Préférez donc consulter l'original ci-dessus, plutôt que sa copie interprétée !

Souhaitant uniquement intervenir sur des sujets techniques dans un but d'entraide, je n'alimenterai pas sur ce forum un nouveau "Troll" de ses intervenants principaux. L'ensemble de leurs publications montrant clairement leur volonté, différente de la mienne.

Anonyme a dit…

Bonjour,
Je suis confronté moi aussi à un pb de doublon.
En fait j'ai importé un fichier Clarion par ODBC que j'ai transformé en fichier HF, j'ai indiqué un ID auto (4 octets). Ce fichier contient une dizaine d'enreg simple (fichier fournisseur).
Lorsque j'en ajoute un, l'ID part à 1...
Par contre avec ce même fichier "fournisseur" vide car créé dans un autre répertoire, l'incrémentation fonctionne bien.
Mon pb c'est que cela se passe pour l'ensemble (une trentaine) des fichiers avec des données importées !!!
Si une solution simple est connue merci de me la faire savoir...

Elian Lacroix a dit…

Il faut exécuter WDOPTIMISEUR, son option de "révision complète". Elle recalcule la prochaine valeur à donner à l'identifant, en fonction du contenu du fichier.

Anonyme a dit…

Effectivement WDOptimiseur règle le pb!
Toutefois cette solution n'est valable que sur le poste de dévelop. ; je ne me vois pas passer les fichiers (avec des ID) de tous les clients à la moulinette sur mon poste !!
J'ai donc cherché plutot par du code:
J'ai essayé hReindexe qui aurait été une solution très simple à mettre en oeuvre, mais les syntaxes utilisées n'ont pas régler le pb.
Du coup, je suis parti sur:
HLitDernier(sFichierAReindexer,sCleIdNom)
HModifie(sFichierAReindexer,hNumEnrEnCours,hFixeIdAuto)
Cela ca marche !!
Mais c'est très lourd à mettre en oeuvre, car il faut coder en dur chaque fichier et chaque clé et c'est épouvantable en terme de suivi.
Aussi, j'ai essayé d'élaborer une procédure générique, pour gagner en vitesse je me suis limité aux clés simples avec Id unique.
la voici:

PROCEDURE ReconstruireIdAuto()

sListeFichierAReindexer est une chaîne
sFichierAReindexer est une chaîne
sListeCle est une chaîne
sCleId est une chaîne
sCleIdNom est une chaîne

Sablier()
// liste les fichiers décrit dans l'analyse
sListeFichierAReindexer = HListeFichier()

// le code ci dessous fonctionne il me permet de réparer les Id Auto...
// Parcours de la chaîne contenant la liste des fichiers trouvés:
POUR TOUTE CHAINE sFichierAReindexer DE sListeFichierAReindexer SEPAREE PAR RC

// voir aussi: hListeRubrique puis NomFichier.NomRubrique..typeclé retourne si clé unique ou pas
sListeCle = HListeClé(sFichierAReindexer,hLstClé+hLstDétail)
POUR TOUTE CHAINE sCleId DE sListeCle SEPAREE PAR RC
//sCleId = ExtraitChaîne(sListeCle, rangPremier,RC)
SI ExtraitChaîne(sCleId,5) = 1 ALORS // clé unique ; je peux directement utilisé un N° de rubrique car séparée par "TAB"
sCleIdNom = ExtraitChaîne(sCleId,1)
SI HLitDernier(sFichierAReindexer,sCleIdNom) = Vrai ALORS
//si pas hmodifie(culture,hNumEnrEnCours,hRecalculeIdAuto) ALORS // retourne le dernier Id (mais n'incrémente pas)
SI PAS HModifie(sFichierAReindexer,hNumEnrEnCours,hFixeIdAuto) ALORS // marche réincrémente les Id
Info("erreur en reconstitution des Id automatiques sur le fichier: " + sFichierAReindexer)
FIN
FIN
FIN
FIN
// réindexation des fichiers décrit dans l'analyse
//SI pas HRéindexe(sFichierAReindexer, hNdxNormal) ALORS // fonctionne mais ne me permet pas de réparer les Id Auto...
// Info("Problème de réindexation du fichier " + sFichierARéindexer)
//FIN
FIN
Sablier(Faux)

Bien que cela me donne satisfaction, je pense que des solutions plus simples (type hReindexe) devraient exister, d'autant qu'au vu des post cela semble un pb assez récurrent et qui peut être catastophique pour de grosses bases de données...
JM Dufour

Anonyme a dit…

Merci beaucoup pour cette explication.
Nous avions un problème similaire qui a pû être réglé avec ces manipulations !

Encore merci !

LL - Porsche France