Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

DMax et acces concurrent ??

4 réponses
Avatar
Didier Fraisse
Bonjour

Dans une appli que je reprends, j'ai quelques portions de code de ce type

Identifiant = DMax("[Champs]","Table","Condition") + 1

Je m'interroge sur le comportement de DMax en environnement
multi-utilisateur.
N'y a-t-il pas le risque que 2 utilisateurs obtiennent le même identifiant ?
Si oui, comment protéger cette section de code ou comment la modifier ?

Merci d'avance
Didier

4 réponses

Avatar
Raymond [mvp]
Bonjour.

Même en environnement multi-utilisateurs, il y a très peu de chances que
deux utilisateurs demandent en même temps le prochain numéro. cette demande
se fait immédiatement dans l'événement Form-beforeupdate et le champ de la
table est immédiatement mis à jour par l'événement Form_Update. Si malgre
cela, au 1/10 de seconde près, le même numéro était demandé, le second
provoquerait une erreur de clé primaire en double. dans ce cas prévoir une
boucle pour demander en permanence le prochaine numéro jusqu'à ce qu'un
numéro soi libre.
--
@+
Raymond Access MVP
http://OfficeSystem.Access.free.fr/
http://users.skynet.be/mpfa/ pour débuter sur le forum


"Didier Fraisse" a écrit dans le message de news:
41bab85e$0$3808$
Bonjour

Dans une appli que je reprends, j'ai quelques portions de code de ce type

Identifiant = DMax("[Champs]","Table","Condition") + 1

Je m'interroge sur le comportement de DMax en environnement
multi-utilisateur.
N'y a-t-il pas le risque que 2 utilisateurs obtiennent le même identifiant
?
Si oui, comment protéger cette section de code ou comment la modifier ?

Merci d'avance
Didier


Avatar
Daniel Carollo
Bonjour Didier!

Voila un de mes dadas... Depuis toujours je prone l'utilisation des
NumeroAuto qui se comportent tres bien, justement pour pallier aux problemes
pour les applications en environement multi-utilisateurs.

En effet, dans la fonction tres simple que vous montrez, il n'y a rien qui
empeche plusieurs utilisateurs d'utiliser cette fonction au meme moment * et
d'obtenir le meme resultat. Tous ces utilisateurs vont donc essayer de creer
des enregistrements avec le meme identifiant.

La seule facon de remedier a cela est de serialiser la creation de
l'identifiant, pour qu'un seul utilisateur ne puisse creer qu'un seul
identifiant a la fois.

En general, cela passe par un enregistrement unique dans une table consacree
a cette fonction. Le candidat a un nouvel identifiant essaie de verrouiller
(en lecture-ecriture) l'enregistrement qui a la derniere valeur. Si le
verrouillage ne succede pas, on attend un certain temps, et on re-essaie.
Quand il finit par succeder, on determine la prochaine valeur, on cree ce
qui est necessaire (le minimum) de l'enregistrement voulu, on met a jour la
valeur, on leve le verrou, et on finit le boulot (s'il y avait des choses
autres que le minimum) sur l'enregistrement.
Il peut etre desirable d'enclore toute cette procedure dans une transaction
(tout du moins la partie "centrale", celle qui creee le nouvel identifiant
et le nouvel enregistrement).
Le but du jeux est de reduire le temps passe a "mettre en place le verrou -
creer le nouvel identifiant - creer le nouvel enregistrement - lever le
verrou", puisqu'il y a des chances qu'un autre utilisateur attende pour
faire la meme chose.

J'ai lance (et relance) un defi il y a pas mal de temps, en fait presque a
chaque fois que quelqu'un donne un fonction du meme type que ci-dessous
comme "solution efficace pour le remplacement des Numeros Auto". Le defi est
de mettre ici le code d'une fonction qui soit simple et elegante pour faire
le meme boulot, et qui fonctionne correctement en mode multi-utilisateurs.

Jusqu'a present, personne n'a encore releve le defi. Peut-etre est-ce
l'absence de recompense qui rends les candidats timides ;-)

Je sais que c'est possible de le faire, puisque j'ai eu a le faire dans un
projet il y a quelque temps. Mais a mon avis, ce n'est pas des plus simples,
et c'est surtout beaucoup plus difficile que de gerer les problemes de
"trous" qui sont la raison principale qui fait que les programmeurs en herbe
evitent les numeros auto.


* Quand je dis "en meme temps", c'est en fait deux temps dont la difference
n'est pas significative a l'echelle de l'operation en cours. Cela pourrait
etre quelques micro ou millisecondes pour une fonction rapide, mais peut
s'etendre jusqu'a plusieurs minutes (voire meme heures) lorsqu'il y a des
interventions humaines dans le flot de calcul.

J'espere que ca vous aide quelque peu dans votre reflexion...

--
Daniel :-)

Computing Technologies International - www.computing-tech.com - We
provide solutions...


"Didier Fraisse" wrote in message
news:41bab85e$0$3808$
Bonjour

Dans une appli que je reprends, j'ai quelques portions de code de ce type

Identifiant = DMax("[Champs]","Table","Condition") + 1

Je m'interroge sur le comportement de DMax en environnement
multi-utilisateur.
N'y a-t-il pas le risque que 2 utilisateurs obtiennent le même identifiant
?

Si oui, comment protéger cette section de code ou comment la modifier ?

Merci d'avance
Didier


Avatar
Didier Fraisse
Bonjour Didier!

Voila un de mes dadas... Depuis toujours je prone l'utilisation des
NumeroAuto qui se comportent tres bien, justement pour pallier aux problemes
pour les applications en environement multi-utilisateurs.

En effet, dans la fonction tres simple que vous montrez, il n'y a rien qui
empeche plusieurs utilisateurs d'utiliser cette fonction au meme moment * et
d'obtenir le meme resultat. Tous ces utilisateurs vont donc essayer de creer
des enregistrements avec le meme identifiant.

La seule facon de remedier a cela est de serialiser la creation de
l'identifiant, pour qu'un seul utilisateur ne puisse creer qu'un seul
identifiant a la fois.

En general, cela passe par un enregistrement unique dans une table consacree
a cette fonction. Le candidat a un nouvel identifiant essaie de verrouiller
(en lecture-ecriture) l'enregistrement qui a la derniere valeur. Si le
verrouillage ne succede pas, on attend un certain temps, et on re-essaie.
Quand il finit par succeder, on determine la prochaine valeur, on cree ce
qui est necessaire (le minimum) de l'enregistrement voulu, on met a jour la
valeur, on leve le verrou, et on finit le boulot (s'il y avait des choses
autres que le minimum) sur l'enregistrement.
Il peut etre desirable d'enclore toute cette procedure dans une transaction
(tout du moins la partie "centrale", celle qui creee le nouvel identifiant
et le nouvel enregistrement).
Le but du jeux est de reduire le temps passe a "mettre en place le verrou -
creer le nouvel identifiant - creer le nouvel enregistrement - lever le
verrou", puisqu'il y a des chances qu'un autre utilisateur attende pour
faire la meme chose.

J'ai lance (et relance) un defi il y a pas mal de temps, en fait presque a
chaque fois que quelqu'un donne un fonction du meme type que ci-dessous
comme "solution efficace pour le remplacement des Numeros Auto". Le defi est
de mettre ici le code d'une fonction qui soit simple et elegante pour faire
le meme boulot, et qui fonctionne correctement en mode multi-utilisateurs.

Jusqu'a present, personne n'a encore releve le defi. Peut-etre est-ce
l'absence de recompense qui rends les candidats timides ;-)

Je sais que c'est possible de le faire, puisque j'ai eu a le faire dans un
projet il y a quelque temps. Mais a mon avis, ce n'est pas des plus simples,
et c'est surtout beaucoup plus difficile que de gerer les problemes de
"trous" qui sont la raison principale qui fait que les programmeurs en herbe
evitent les numeros auto.


* Quand je dis "en meme temps", c'est en fait deux temps dont la difference
n'est pas significative a l'echelle de l'operation en cours. Cela pourrait
etre quelques micro ou millisecondes pour une fonction rapide, mais peut
s'etendre jusqu'a plusieurs minutes (voire meme heures) lorsqu'il y a des
interventions humaines dans le flot de calcul.

J'espere que ca vous aide quelque peu dans votre reflexion...

Bonjour Daniel


Pour être tout à fait exact, ce n'est qu'une partie du code.
Le numéro attribué est de la forme
Site sur 1 caractère (codifié de 1 à 9)
Exercice sur 2 caractères (de 00 à 99), je verrais en 2099 pour modifier
Période sur 2 caractères (de 01 à 13)
N° d'ordre dans la période sur 5 caractères (de 00000 à 99999)
le DMax ne sert qu'à attribuer le N° suivant dans la période sinon on
recommence à 1
Tout celà pour dire que le numéroauto est inutilisable dans ce cas
malgrè ses avantages indéniables.

Alors que faire
Une table Compteur avec un accès exclusif ?
Utilisé un sémaphore système (pour les courageux)?

Avatar
Daniel Carollo
Bonjour Didier!

Votre reponse evoque en moi deux reflexions.

La premiere, d'ordre general: il est aussi fare que felu de mettre en place
(ou d'accepter de mettre en place) des numerotations aussi sottes que
grenues SI ELLES DOIVENT SERVIR D'IDENTIFIANT. Je verrais plutot ce champ
comme un champ caclule au niveau des rapports (ou a la rigueur sur des
formulaires), vraiment a la rigueur stocke dans la table comme champ
supplementaire (mais alors on commence a glisser sur la pente savonneuse)
mais surtout pas comme champ de clef primaire d'une table.
Si j'avais devant moi un client qui insisterait pour avoir un "identifiant"
de la sorte que vous decrivez, je ferais des pieds et des mains pour
l'encourager a laisser tomber l'usage de ce barbarisme.
Si la presence de cette horrifiante chose est absolument necessaire (un
numero de serie, par exemple), alors j'accepterais de le mettre en tant que
champ calcule. Il peut "apparaitre" au monde exterieur comme l'identifiant
de l'objet concerne, mais au niveau de la table (et des relations avec les
autres tables), l'identifiant est une clef primaire basee sur un numero
auto, et hop! ni cu ni vonnu, le tout est joue.

Toujours dans l'ordre general, en m'appuyant sur votre exemple, voici
pourquoi je pense que l'utilisation d'un DMax() est une tres mauvaise idee
pour generer un identifiant. Vous dites
N° d'ordre dans la période sur 5 caractères (de 00000 à 99999)
Je vais donc presumer que le quidam qui a emis l'idee de cette numerotation

absurde a pris un facteur de securite de 10, et qu'en fait il peut y avoir
jusqu'a 10 000 enregistrements par periode.
Période sur 2 caractères (de 01 à 13)
Cela me rappelle un client qui voulait des mois ronds d'exactement 4

semaines, donc 13 periodes par an. Ils sont revenus, apres moultes echecs, a
un calendrier traditionel lors de la mise en place de SAP.
Je vais donc presumer que la production se fait de facon continue (les 3 x
8) sur 5 jours par semaine, donc 20 jours par periode, 480 heures par
periode.
On a donc un besoin de 20 nouveaux numeros par heure.
Si 3 postes generent ces numeros, la probabilite de collision est non
negligeable. Elle depend du temps que prend la fonction pour generer ce
nouveau numero. Pour une fonction qui prend une minute a executer, il y a
une chance sur 1000 d'avoir une collision (en fait une probabilite un peu
plus elevee, mais j'arrondis). Sur 10 000 enregistrements par mois, on peut
donc s'attendre a une dizaine de collisions, ce n'est plus vraiment fiable,
ca...
Par contre, si la fonction prend deux minutes, la probabilite passe a 8 fois
plus. Une centaine de collisions par mois, ce n'est pas negligeable du tout.
La fonction devra aller taper dans une table qui aura plusieurs centaines de
milliers d'enregistrements, sur un reseau dont on ne connait a priori pas
les caracteristiques.

La deuxieme reflexion, d'ordre plus particulier, concerne le besoin present.
Je serais fort surpris que les informations necessaires a creer le fameux
champ soient enregistrees dans des champs de ce meme enregistrement, ou
soient aisement calculables (date, periode, exercice). Pour generer le champ
voulu, je prendrait plutot la decision d'avoir un champ numero auto comme
identifiant de l'enregistement. J'aurais aussi une requete qui recupere le
dernier numero auto utilise dans une periode, par exercice. Le champ
d'identification "externe" serait donc la concatenation diabolique voulue,
le calcul du numero d'ordre etant le numero auto moins le dernier numero
utilise dans l'exercice precedent. Le seul changement est qu'il n'y aurait
alors pas de numeros d'ordre identique pour deux sites differents...

Voila ces quelques reflexions. Bonne soiree.


--
Daniel :-)

Computing Technologies International - www.computing-tech.com - We
provide solutions...

"Didier Fraisse" wrote in message
news:41bae04c$0$3797$
Bonjour Daniel

Pour être tout à fait exact, ce n'est qu'une partie du code.
Le numéro attribué est de la forme
Site sur 1 caractère (codifié de 1 à 9)
Exercice sur 2 caractères (de 00 à 99), je verrais en 2099 pour modifier
Période sur 2 caractères (de 01 à 13)
N° d'ordre dans la période sur 5 caractères (de 00000 à 99999)
le DMax ne sert qu'à attribuer le N° suivant dans la période sinon on
recommence à 1
Tout celà pour dire que le numéroauto est inutilisable dans ce cas
malgrè ses avantages indéniables.

Alors que faire
Une table Compteur avec un accès exclusif ?
Utilisé un sémaphore système (pour les courageux)?