Précédent   Forum des professionnels en informatique > Bases de données > MySQL > SQL Procédural
SQL Procédural Forum d'entraide sur les triggers, les procédures stockées et les fonctions en MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 23/01/2007, 17h20   #1
Nouveau Membre du Club
 
Inscription : juin 2005
Messages : 309
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 309
Points : 29
Points : 29
Envoyer un message via MSN à AsmCode
Par défaut Questions diverses sur MySQL 5.0

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
AsmCode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2007, 18h01   #2
Expert Confirmé
 
Avatar de berceker united
 
Développeur informatique
Inscription : février 2005
Messages : 2 982
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2005
Messages : 2 982
Points : 3 567
Points : 3 567
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 !...
berceker united est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2007, 19h07   #3
Nouveau Membre du Club
 
Inscription : juin 2005
Messages : 309
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 309
Points : 29
Points : 29
Envoyer un message via MSN à AsmCode
Citation:
Envoyé par berceker united
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.
Salut, mais je veux éviter de bloquer la table justement, sinon tout les agendas seront bloqués ce qui n'a pas de sens. Seul 1 agenda pour 1 date doit être bloqué.

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.
AsmCode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2007, 22h00   #4
Membre Expert
 
Avatar de Adjanakis
 
Inscription : avril 2004
Messages : 734
Détails du profil
Informations personnelles :
Localisation : France, Pas de Calais (Nord Pas de Calais)

Informations forums :
Inscription : avril 2004
Messages : 734
Points : 1 281
Points : 1 281
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
Adjanakis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2007, 22h45   #5
Nouveau Membre du Club
 
Inscription : juin 2005
Messages : 309
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 309
Points : 29
Points : 29
Envoyer un message via MSN à AsmCode
Citation:
Envoyé par Adjanakis
Bonjour,

Si le storage Engine est InnoDB, cette page pourrait être intéressante :
http://dev.mysql.com/doc/refman/5.0/...ing-reads.html
Salut, en fait j'utilise l'autre type, mais je pourrais toujours migrer. Mais ce que je me demandais c'est si j'utilises une stored procedure, quand mysql exécute une stored procedure est-ce qu'il est multi-tâche ? peut-il exécuter la même stored procedure (ou une autre requête) pendant qu'il est en train d'en exécuter une ?

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.
AsmCode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2007, 09h27   #6
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 540
Points : 9 540
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 ), et à tester toutes les hypothèses. Arriver à un bon niveau d'isolation sans bloquer tout le système est un sacré boulot !
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2007, 09h47   #7
Expert Confirmé
 
Avatar de berceker united
 
Développeur informatique
Inscription : février 2005
Messages : 2 982
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2005
Messages : 2 982
Points : 3 567
Points : 3 567
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 !...
berceker united est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2007, 15h57   #8
Nouveau Membre du Club
 
Inscription : juin 2005
Messages : 309
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 309
Points : 29
Points : 29
Envoyer un message via MSN à AsmCode
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 ?
AsmCode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2007, 17h09   #9
Expert Confirmé
 
Avatar de berceker united
 
Développeur informatique
Inscription : février 2005
Messages : 2 982
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2005
Messages : 2 982
Points : 3 567
Points : 3 567
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 !...
berceker united est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2007, 17h32   #10
Nouveau Membre du Club
 
Inscription : juin 2005
Messages : 309
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 309
Points : 29
Points : 29
Envoyer un message via MSN à AsmCode
Citation:
Envoyé par berceker united
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.
Ok Dans ce cas tout est correct, car mon application met déjà à jour le lock si il envoie un update a toutes les minutes pour effacer les lock expirés.

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.
AsmCode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2007, 18h24   #11
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 540
Points : 9 540
Code :
WHERE EXISTS (SELECT 1 FROM Agenda WHERE Agenda Id = 1)
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2007, 18h29   #12
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 540
Points : 9 540
Plus simple (enfin, sans sous-requête) :
Code :
1
2
3
4
5
6
 
 INSERT INTO Table1 
(id, nom) 
SELECT 1, 'John Doe'
FROM Agenda 
WHERE Agenda Id = 1
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2007, 18h40   #13
Nouveau Membre du Club
 
Inscription : juin 2005
Messages : 309
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 309
Points : 29
Points : 29
Envoyer un message via MSN à AsmCode
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 ?
AsmCode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2007, 16h23   #14
Nouveau Membre du Club
 
Inscription : juin 2005
Messages : 309
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 309
Points : 29
Points : 29
Envoyer un message via MSN à AsmCode
Personne n'aurait une idée pour ça ?
AsmCode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2007, 16h35   #15
Expert Confirmé
 
Avatar de berceker united
 
Développeur informatique
Inscription : février 2005
Messages : 2 982
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2005
Messages : 2 982
Points : 3 567
Points : 3 567
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 !...
berceker united est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h34.


 
 
 
 
Partenaires

Hébergement Web