|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Nouveau Membre du Club
![]() |
Bonjour, je fais une application client avec une bd mysql. Jusqu'ici j'étais avec 4.1 mais pour une question pratique j'envisage de passer à la 5.0 pour les stored procedures. L'application est un genre d'agenda électronique.
Mais comme la bd est partagé entre les clients, donc n'importe qui peut ajouter/modifier/supprimer des rendez-vous, etc. Je m'étais fait un genre de système pour barrer une journée d'un agenda pendant que l'utilisateur la modifie pour ne pas que les autres puissent changer les données. Imaginez quand un usager veut créer un rendez-vous et avant qu'il ne sauvegarde le rendez-vous un autre usager a déjà enregistrer un rendez-vous qui rentre en conflit avec les heures choisis de l'autre. Et si je fais dans visual basic un if then else pour savoir si c'est toujours libre, pendant que vb fait son if then else, ça n'empêche pas un autre usager d'envoyer une requête SQL au serveur pour modifier les données, donc cette solution n'est pas valide, même si les chances sont faibles. Alors je me suis dit qu'avec les stored procedures je pourrais me passer de barrer la journée et faire un if then else, puisque (à moins que je me trompe) quand MySQL exécute la stored procedure, rien ne peut se passer pendant ce temps, puisque MySQL n'exécute qu'une seule requête à la fois. Mais j'aurais besoin d'une confirmation Car il sajit d'un agenda électronique dont les rendez-vous sont importants et ne doivent pas être écrasés par erreur si plusieurs usagers essaie de rentrer des rendez-vous dans les même heures ou tenter de modifier des données qui ont déjà été modifiés pendant leur dernier 'refresh' Merci |
|
|
00
|
|
|
#2 |
|
Expert Confirmé
![]() Développeur informatique Inscription : février 2005 Messages : 2 982 ![]() |
Tu peux bloquer une table SQL Pendant que tu fais ta soupe. Ceci évite les risques de conflit ou d'ecrasement de l'information. Mais attention, il faut bien lire la doc pour jouer avec les histoires de lock de table.
__________________
Mon avatar ? Ce n'est rien, c'est juste la tête que je fais lorsque je vois un code complètement frappa dingue !... |
|
|
00
|
|
|
#3 | |
|
Nouveau Membre du Club
![]() |
Citation:
Ma structure est la suivante: Table: Agenda Agenda_Id Agenda_Name Table Caldate Cal_Id Cal_AgendaId Cal_Date et dans une autre table je mettais un enregistrement comme quoi le Cal_Id (disons 1) était bloqué par l'usagé xyz sur tel pc. De cette façon les autres peuvent modifier leurs agendas, seul l'agenda pour la date xyz est bloqué pendant que l'usager fait ses modifs. Mais par cette façon, un truc m'embête c'est que si l'usagé sort de l'application anormalement (plantage du pc, connexion réseau rompue, plantage du exe, etc) L'info de blocage reste dans la bd. Ça ne débloque que si l'usager quitte le formulaire avec le bouton quitter ou quand il démarre l'application. Pour 5.0 je pensais mettre un triggers, mais je ne sais pas comment ça pourrait fonctionner. Je crois que les triggers sont faits seulement pour se déclencher à aux changements sur une table. Alors ce que j'avais fait pour ça avec 4.1 c'est que quand l'usagé est en train de faire des modifs, il met à jour l'heure du lock aux 30 sec et les autres instances de l'application qui tournent(y compris lui-même en fait) fait un update à toute les minutes pour enlever les lock qui sont expiré de plus de 30 sec. Ça fonctionne #1 mais je me demande si il n'y aurait pas une façon plus simple, plus élégante. J'utilise un timer, mais même dans une application client-serveur il y a quand même un timer qui vérifie l'arrivé de messages donc ça revient au même. |
|
|
|
00
|
|
|
#4 |
|
Membre Expert
![]() ![]() Inscription : avril 2004 Messages : 734 ![]() |
Bonjour,
Si le storage Engine est InnoDB, cette page pourrait être intéressante : http://dev.mysql.com/doc/refman/5.0/...ing-reads.html
__________________
Pensez au tag
|
|
|
00
|
|
|
#5 | |
|
Nouveau Membre du Club
![]() |
Citation:
Je crois que InnoDB pourrait me convenir, car je n'aurais qu'à faire un Select for update, les enregistrements seraient barrés. Et pour ce qui est des ajouts, l'usagé qui enregistrera ses ajouts en deuxième se verra recevoir un message comme quoi les ajouts qu'il tente de faire entre en conflit avec des enregistrements existants, si conflit il y a. Qu'en pensez-vous ? Sur ce, je me demandais si il y aurait moyen de déterminer quels conflits il y a, peut-être une stored procedure avec des variables Out ? Mais je me demande ce qui est mieux, que l'usagé se rende compte qu'il ne peut enregistrer ses nouveaux trucs, car ça entre en conflit, car un autre usagé l'a devancé entretemps ou bien qu'il sache immédiatement qu'il ne peut pas, car la journée de l'agenda x est barré et qu'il doit attendre que l'usagé z sorte ou finisse ses trucs ? Je pourrais toujours faire un lock par les heures au lieu de par les journées, mais c'est que un usager ne sait pas toujours d'avance ce qu'il va faire, un client apelle, il veut un rendez-vous on lui demande à quelle heure il souhaite son rendez-vous, ou on lui propose une heure libre et on lui demande si ça lui convient, mais les changements ne sont pas nécessairement uniquement au niveau des heures, on pourrait avoir a ajouter des notes sur cette journée, y déplacer un rendez-vous, etc. C'est assez imprévisible. |
|
|
|
00
|
|
|
#6 |
![]() ![]() ![]() Antoine DinimantConsultant en Business Intelligence Inscription : octobre 2006 Messages : 5 854 ![]() |
La solution est clairement les transactions InnoDB, qui te permettent un lock ligne par ligne.
MySQL est effectivement capable d'exécuter plusieurs procédures concurrentes à la fois, d'où l'importance de mettre tes procs dans des transactions. Tu as intérêt à lire de très prêt la doc et/ou un bon tutoriel (ou un bon bouquin |
|
|
00
|
|
|
#7 |
|
Expert Confirmé
![]() Développeur informatique Inscription : février 2005 Messages : 2 982 ![]() |
J'avoue que c'est un domaine très stratégique que peut utilisent car la moindre erreur peut effectivement être pire que ce que tu cherche à éviter.
__________________
Mon avatar ? Ce n'est rien, c'est juste la tête que je fais lorsque je vois un code complètement frappa dingue !... |
|
|
00
|
|
|
#8 |
|
Nouveau Membre du Club
![]() |
réflexion faites, à moins que je ne me trompes, je crois que innodb pourrait me servir pour les delete en cascades dû aux clefs étrangères qui sont plus simple que MyIsam, mais pour ce qui est des lock, cela ne correspond pas à mes besoins, car je ne peux pas barrer quelque chose qui n'existe pas, car il ne sajit pas dans mon application de barrer des enregistrements précis, car on ne sait pas sur lequels ont va travailler, donc je crois que barrer journée reste la meilleure solution. Car il ne sajit pas non plus de simplement barrer, mais bien que les usagers sache ce qui se passe, qui est en train de modifier des trucs, sur quel pc, etc.
Par contre, pour ce qui est de l'expiration de mon lock. Est-ce qu'il y a moyen de créer un enregistrement dans une table et il s'efface si on ne fait pas de select dessu au bout d'un certain temps ? Je voudrais que mon lock s'efface de lui-même si par exemple le client qui a créé ce lock se déconnecte ou bien ne met plus a jour son lock au lieu que chaque application qui tourne fasse un update si c'est expiré depuis plus de 1 min. Aussi je me demandais si il y avait moyen en SQL de faire un INSERT ou UPDATE avec une condition IF qui implique d'autres tables ? Par exemple: INSERT INTO Table1 (id, nom) VALUES (1, 'John Doe') WHERE (SELECT Agenda_Id FROM Agenda WHERE Agenda Id = 1) = 1 Quelque chose du genre, pour s'assurer que le insert se fait à condition que le select renvoit 1 enregistrement ? |
|
|
00
|
|
|
#9 |
|
Expert Confirmé
![]() Développeur informatique Inscription : février 2005 Messages : 2 982 ![]() |
Concernant si un enregistrement a été consulté je crois que tu devrais le gérer par toi même car il n'est pas possible de savoir nativement si un enregistrement a été consulté ou non. Au niveau de la table oui. Il n'existe pas de déclencheur sur le select. Par contre je pense que tu peux faire une sous requête dans le select. En gros un select qui imbrique un update qui lui va mettre à jour une date.
__________________
Mon avatar ? Ce n'est rien, c'est juste la tête que je fais lorsque je vois un code complètement frappa dingue !... |
|
|
00
|
|
|
#10 | |
|
Nouveau Membre du Club
![]() |
Citation:
Je me disais que je pourrais faire la même chose si je veux gérer un système de login sur l'application. Mais pour dernière question: Par exemple: INSERT INTO Table1 (id, nom) VALUES (1, 'John Doe') WHERE (SELECT Agenda_Id FROM Agenda WHERE Agenda Id = 1) = 1 Est-ce que c'est possible ? Car je n'ai pas réussi à trouver la syntaxe exacte. Une autre chose, est-il possible de mettre un timer sur le serveur ? Une stored procedure qui s'exécute à un intervale déterminé ? Ça m'éviterais de faire la mise à jour du lock au niveau de l'application. |
|
|
|
00
|
|
|
#11 |
![]() ![]() ![]() Antoine DinimantConsultant en Business Intelligence Inscription : octobre 2006 Messages : 5 854 ![]() |
Code :
WHERE EXISTS (SELECT 1 FROM Agenda WHERE Agenda Id = 1) |
|
|
00
|
|
|
#12 | ||
![]() ![]() ![]() Antoine DinimantConsultant en Business Intelligence Inscription : octobre 2006 Messages : 5 854 ![]() |
Plus simple (enfin, sans sous-requête) :
Code :
|
||
|
|
00
|
|
|
#13 |
|
Nouveau Membre du Club
![]() |
Super merci
Mais pour ce qui est du timer sur la stored procedure ? J'ai pensé mettre une boucle dans la stored procedure mais elle va s'exécuter tant que le serveur sera opérationnel, mais comment savoir à partir de l'application si la boucle de la stored procedure est démarré ou non pour la démarrer au besoin et pour ne pas la démarrer 10 fois si il y a 10 instances de l'application qui tourne ? |
|
|
00
|
|
|
#14 |
|
Nouveau Membre du Club
![]() |
Personne n'aurait une idée pour ça ?
|
|
|
00
|
|
|
#15 |
|
Expert Confirmé
![]() Développeur informatique Inscription : février 2005 Messages : 2 982 ![]() |
C'est une technique de chien malade mais tu places un flag dans une table. Tant qu'il tourne il refraichi le temps. Si now() - temps enregistré est au de la de x alors c'est qu'il ne tourne plus.
__________________
Mon avatar ? Ce n'est rien, c'est juste la tête que je fais lorsque je vois un code complètement frappa dingue !... |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com