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 ?
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 ;-)
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
;-)
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 ;-)
Yannick
Bonjour tout le monde
Voici une méthode n'utilisant pas les transactions
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
Bonjour tout le monde
Voici une méthode n'utilisant pas les transactions
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.
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.
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 ;-)
Yannick a écrit :
Bonjour tout le monde
Voici une méthode n'utilisant pas les transactions
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
;-)
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 ;-)
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
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)