|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||||
![]() ![]() Dinobogan Shelashyningénieur étude et développement Inscription : juin 2007 Messages : 3 276 ![]() |
Bonjour à tous,
je fouine partout depuis 2 jours dans les forums et les doc mais sans succès. Voici le code (fortement simplifié) de la procédure stockée qui permet de faire des débits sur un compte (je ne met pas la gestion des erreurs par exemple) : Code :
Thread_1 recupere NOUVEAU_SOLDE_1 Thread_2 recupere NOUVEAU_SOLDE_1 Thread_1 modifie sa valeur NOUVEAU_SOLDE_1 en NOUVEAU_SOLDE_2 Thread_2 modifie sa valeur NOUVEAU_SOLDE_1 en NOUVEAU_SOLDE_3 Thread_1 update SOLDE avec NOUVEAU_SOLDE_2, puis commit Thread_2 update SOLDE avec NOUVEAU_SOLDE_3, puis commit le calcul de la nouvelle valeur NOUVEAU_SOLDE_2 est perdue et écrasée par le Thread_2. Donc le débit fait par Thread_1 n'est jamais répercuté sur le compte client :-( Il aurait fallut que Thread_2 patiente jusqu'au commit de Thread_1 pour qu'il utilise NOUVEAU_SOLDE_2 au lieu de NOUVEAU_SOLDE_1. J'ai trouvée une solution que je trouve très moche. La voici : Code :
Mais y-a-t-il une solution propre et standard ? Dans mes recherches, j'ai donc exploré pleins de techniques, trouvées sur les forums et autres doc : - débuter la transaction avant le select, en mettant un "at isolation" sur le select, mais j'ai un deadlock - mettre un holdlock sur le select, mais ça ne change rien Il y a aussi la solution du curseur sur le SELECT, avec un "FOR UPDATE". Mais ce select renvoit soit une ligne, soit aucune ligne. Donc faire un curseur me parait un peu lourd. De plus j'ai peur que ça utilise trop de ressources. En effet, cette procédure est appelée sur la journée en moyenne 900 fois par secondes, et atteint en pic deux fois par jour 1400 fois par secondes. Et pour la table COMPTE, la voici : Code :
PS : merci d'avoir été jusqu'au bout de mon explication ;-) |
||||||
|
|
00
|
|
|
#2 | |||||
![]() ![]() |
Citation:
Une alternative consiste à avoir une table de type sémaphore pour faire un lock "logique". Le problème est que cela risque de créer un "hot point", avec les problèmes de perfs associées. Le holdlock (ou isolation 3) aurait à priori dû marcher, pour autant que la transaction est démarrée avant le select: Code :
Michael
__________________
Michael Peppler Membre de TeamSybase - www.teamsybase.com "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson |
|||||
|
|
00
|
|
|
#3 |
![]() ![]() |
Après un petit test je vois que le "select ... at isolation 3" pose un verrou de type shared, ce qui ne sert évidemment à rien.
Donc ta première solution semble la plus adaptée. Michael
__________________
Michael Peppler Membre de TeamSybase - www.teamsybase.com "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson |
|
|
00
|
|
|
#4 |
![]() ![]() Dinobogan Shelashyningénieur étude et développement Inscription : juin 2007 Messages : 3 276 ![]() |
Merci beaucoup !
Je garde donc ma solution pas super propre avec l'update |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com