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

[HS] Equivalent des locks en sql

15 réponses
Avatar
patrice
Bonjour

Y'a eu un thread récent sur les locks de mysql.
D'apres ce que j'ai lu, il semblerait qu'il faille éviter de les utiliser.

Autant pour mettre a jour une fiche, "le dernier qui parle a raison" me
semble une bonne méthode.
Mais comment se gere par exemple la vente de produit en stock.

En hf (séquentiel indexé) standard, on ferait un truc du genre :
verouille(fiche_produit)
si qte_dispo>=quantité_demandé alors qte_dispo=qte_dispo -
quantité_demandé, enregistrer(fiche_produit)
sinon
deverouille(fiche_produit)
afficher "Cette quantité n'est pas disponible"

Cela permet d'etre sur de ne vendre que ce que l'on a.
Mais que devient cet algorithme en sql, mysql, mssql ? existe une facon
standard de procéder ?

5 réponses

1 2
Avatar
Daniel
Gilles a écrit :
Dans son message précédent, Firetox a écrit :
Bonjour,

Tu ne voulais pas un truc "standard"?
Parce que Select for update n'existe pas sur toutes les bases (à
commencer par MS SQL Server)





si et SQLServer va plus loin
sur mySQL quand une ligne est locké par un select for update les
select suivat seront bloqué jusqu' aliberation de la transaction



En SQL 2005?
On n'a pas réussi à avoir le comportement adéquat en SQL 2000, et on
avait abandonné l'idée. Si ca marche en 2000, je reverrais mes procs
immédiatement, tu as un sample?





Si tu passes en niveau transactionnel "serializable" tu devrais résoudre
ton problème. Il suffit d'utiliser le bon mode et de le définir juste
avant la transaction.


Aussi bien Innodb, Oracle, Postgresql, SQlserver.... supportent le
niveau 3 transactionnel.

HF supporte le niveau 0 READ UNCOMMITED, c'est pour cette raison qu'il
faut faire des blocages sous HF, et surtout que le niveau transactionnel
sur HF permet uniquement l'annulation d'opération, mais en rien de
travailler dans un environnement "concurrentiel". Sur un serveur peut
chargé, tout se passera bien, par contre c'est lorsque la charge
augmente que tu commences à avoir des incohérences sur les données
(c'est pareil avec MySQL Isam).


--
suivre ce lien pour répondre:
http://cerbermail.com/?2KrV3YZXnn
Daniel
;-)
Avatar
Yannick
Bonjour tout le monde

Voici une méthode n'utilisant pas les transactions

Soit la table et les rubriques suivantes :

[PRODUIT]
IdProduit - integer
QtteEnStock - boolean

Si 2 utilisateurs veulent en même temps vendre le même produit (les 2
requêtes ne sont pas exécutées en même temps par le serveur SQL, qu el
qu'il soit)
1) SELECT IdProduit,QtteEnStock FROM PRODUIT WHERE ....
2) On stocke les données dans des variables : a = IdProduit, b =
QtteEnStock
3) UPDATE PRODUIT SET QtteEnStock = QtteEnStock - 1 WHERE IdProduit =
a AND QtteEnStock = b

En admettant que le produit dont l'id est 1, a 5 modèle en stock et
que la requête de l'étape 1) est exécutée quasi simultanément par nos
2 utilisateurs, les 2 utilisateurs obtiennent à l'étape 2) les
variables a=1, b=5
Mais à l'étape 3), la première requête exécutée est UPDATE PROD UIT SET
QtteEnStock = QtteEnStock - 1 WHERE IdProduit = 1 AND QtteEnStock = 5
Si tout se passe bien, la rubrique QtteEnStock contient 4. Du coup,
quand le deuxième utilisateur exécute sa requête, il ne se passe rien
car la deuxième condition du where (QtteEnStock = 5) n'est plus
remplie. Il repasse alors à l'étape 1) et peut continuer ainsi tant
que la QttéEnStock est >0.

Suis je bien clair ?

Yannick
Avatar
Yannick
Pardon, il fallait lire :

[PRODUIT]
IdProduit - integer
QtteEnStock - integer

Vous aurez corrigé de vous même.

Désolé
Avatar
Daniel
Yannick a écrit :
Bonjour tout le monde

Voici une méthode n'utilisant pas les transactions

Soit la table et les rubriques suivantes :

[PRODUIT]
IdProduit - integer
QtteEnStock - boolean

Si 2 utilisateurs veulent en même temps vendre le même produit (les 2
requêtes ne sont pas exécutées en même temps par le serveur SQL, quel
qu'il soit)
1) SELECT IdProduit,QtteEnStock FROM PRODUIT WHERE ....
2) On stocke les données dans des variables : a = IdProduit, b > QtteEnStock
3) UPDATE PRODUIT SET QtteEnStock = QtteEnStock - 1 WHERE IdProduit > a AND QtteEnStock = b

En admettant que le produit dont l'id est 1, a 5 modèle en stock et
que la requête de l'étape 1) est exécutée quasi simultanément par nos
2 utilisateurs, les 2 utilisateurs obtiennent à l'étape 2) les
variables a=1, b=5
Mais à l'étape 3), la première requête exécutée est UPDATE PRODUIT SET
QtteEnStock = QtteEnStock - 1 WHERE IdProduit = 1 AND QtteEnStock = 5
Si tout se passe bien, la rubrique QtteEnStock contient 4. Du coup,
quand le deuxième utilisateur exécute sa requête, il ne se passe rien
car la deuxième condition du where (QtteEnStock = 5) n'est plus
remplie. Il repasse alors à l'étape 1) et peut continuer ainsi tant
que la QttéEnStock est >0.

Suis je bien clair ?

Yannick



Bonjour,

généralement lorsqu'on fait un update sur un stock, c'est généralement
suivit d'un insert par exemple sur une commande.

Comment fais tu pour gérer ce cas ? Bien entendu sans blocage et sans
transaction.

--
suivre ce lien pour répondre:
http://cerbermail.com/?2KrV3YZXnn
Daniel
;-)
Avatar
Yannick
Aucune idée.

Je ne faisais que présenter une méthode qui répondait au besoin
initial. Il est vrai que je n'ai pas poussé plus avant la réflexion.

Cette méthode reste néanmoins intéressante. A utiliser dans d'autres
cas peut-être ? :o)

Yannick
1 2