IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

Repérer une modification de la base


Sujet :

Hibernate Java

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 84
    Par défaut Repérer une modification de la base
    Bonjour,

    voici mon problème :

    je charge des informations depuis une base mysql dans une interface gràce à hibernate.

    Je fais des modifications en local (i.e. je ne modifie pas directement la base) par le biais de cette interface.

    Et je sauve (bouton "sauver" ^^) dans la base.

    Le problème est que si 2 personnes utilisent ce logiciel en même temps... ça foire car si (dans cet ordre) un utilisateur A supprime une entrée x et qu'un utilisateur B modifie cette même entrée x, alors au moment de la sauvegarde de B, il va y avoir un problème car x n'existe plus.

    Les solutions que j'envisage sont,

    - Bloquer la base entière pour un seul utilisateur, mais je ne vois pas comment (la fonction TABLE LOCK de MySql ne semble pas appropriée)

    - Vérifier avant de sauvegarder que l'état de la base n'a pas été modifié et, le cas échéant, message d'erreur : "attention, base modifié, blabla" (le principe étant que le logiciel ne devant, dans un usage normal, n'être utilisé que par une personne à la fois)
    Cette solution me semble la plus satisfaisante mais je ne vois pas comment faire pour savoir si la base à été modifiée depuis la dernière sauvegarde à part en créant un gros objet "Base" au chargement et en le comparant à un autre objet "Base" qui serait obtenue en faisant un chargement préliminaire avant toute sauvegarde... J'aimerai VRAIMENT qu'il y ait une autre solution

    Donc si vous avez des idées pour savoir si une base à été modifiée, pour autoriser une seule entité (homme, programme) à accéder à une base ou toute autre idée je vous en serais gré.

    MERCI

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 100
    Par défaut
    Citation Envoyé par gwendal86 Voir le message
    Je fais des modifications en local (i.e. je ne modifie pas directement la base) par le biais de cette interface.
    Je ne comprend pas vraiment ce que ça veut dire. Est-ce que les utilisateurs modifient la base de puis une application client lourd ?

    Ou est-ce que les utilisateurs se connectent à une appli web ? Si c'est le cas hibernate doit résoudre ce problème.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 84
    Par défaut
    en gros je ne travail pas directement avec des objets hibernate.

    Je créé les objets dont j'ai besoin au chargement, ensuite l'utilisateur peut faire toutes les modif qu'il veut sur ces objets (transparent pour lui bien sur) et c'est seulement quand l'utilisateur sauve que je construit des objets hibernate pour mettre à jour la base.

    le principe de fonctionnement c'est :


    ouverture base
    |
    | ---> extraction des données
    |
    fermeture base

    ||
    || --- modif ...
    ||

    ouverture base
    |
    | <--- remplissage de la base
    |
    fermeture base



    Et l'idée, c'est qu'il faudrait que pendant la période "modif", personne ne touche à la base ou, si c'est impossible de faire ça simplement,
    au moins empêcher la phase "remplissage de la base" si la base à été modifiée.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 100
    Par défaut
    Quelle est la raison de ce fonctionnement ?
    Est-ce que ce n'est pas plus simple d'effectuer les modifications sur les objets Hibernate directement ?

  5. #5
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Effectivement, c'est un curieux comportement...

    Tu pourrais peut-être utiliser un verrouillage des enregistrements avant écriture.
    Dans l'idée, ta lecture initiale est bien évidemment non bloquante mais avant écriture (physique), tu recharges les entités avec verrouillage
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    // le chargement
    UnObjet monObjet = session.load(UnObjet.class);
     
    // les modifications (on pourrait fermer la session)
     
    // à la fin
    session.beginTransaction();
     
    // on boucle sur tous les objets à traiter...
    session.load(monObjet.getClass(), maCle, LockMode.UPGRADE);
     
    // on boucle sur tous les objets à mettre à jour
    session.update(monObjet);
     
    session.getTransaction().commit();
    et au commit -> tout se libère
    (si ça ne suffit pas, il faudra fermer la session)

    C'est une idée... j'ai rien d'autre en stock pour le moment
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre chevronné Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Par défaut
    Tu as différentes façon de gérer la concurrence :

    1) Pas de verrouillage : le dernier qui parle à raison
    2) Verrouillage optimiste : chaque enregistrement de chaque table possède un numéro qui correspond à la version de l'enregistrement. Une tentative de modification sur un numéro incrémenté depuis doit se traduire par une erreur (StateStaleException de mémoire avec Hibernate)
    3) Verrouillage pessimiste : consiste à poser un verrou pour la modification. Personne ne peux modifier si la personne ayant posé le verrou n'a pas terminé. Ce qui peut etre tres tres génant si un utilisateur veut consulter une donnée sans la modifier. Il faut prévoir à ce moment là des écrans dédiés à la consultation qui ne posent pas de verrou, ou bien un bouton "modifier" pour poser le lock uniquement lors d'une modif (c'est également le moment de vérifier si les données n'ont pas changées en base pour rafraichir les données affichées).

    Une solution élégante peut être de gérer ca de manière applicative, avec une table de "locks". C'est plus long à coder qu'un lock en bdd, mais ca permet de savoir facilement quel utilisateur possède le lock, de pouvoir forcer à prendre le verrou, de gérer un timeout sur le lock ....

    Au final, le choix dépend du type d'application et de la fréquence des mises à jour simultanées.

    En esperant t'avoir aidé

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 84
    Par défaut
    Merci à tous pour ces informations très utiles.

    Je dois respecter le fonctionnement sus-cité, par ce que... on me le demande (je suis stagiaire ma liberté d'expression est limité )

    Je ne modifie pas directement des objets hibernate car je veut pouvoir faire des modifications dans l'interface, faire des tests avec et si je suis content je sauve, sinon je fait d'autre truc ou je revient à l'état initial de la base.

    Mon application n'a pas pour but d'être utilisé par plusieurs personnes à la fois mais il faut juste que je gère le cas où cela arriverais.

    Je pense donc que le "blocage pessimiste" est la meilleur solution pour moi...

    Si vous avez plus d'info à ce sujet... je vais continuer de chercher de ce coté la en tout cas

    Merci

  8. #8
    Membre chevronné Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Par défaut
    Citation Envoyé par gwendal86 Voir le message
    Mon application n'a pas pour but d'être utilisé par plusieurs personnes à la fois mais il faut juste que je gère le cas où cela arriverais.
    Je pense donc que le "blocage pessimiste" est la meilleur solution pour moi...
    Si ton application n'a pas pour but d'être utilisé par plusieurs personnes, tu peux alors l'exprimer sous la forme d'une contrainte : "l'application ne gère pas les modifications simultanées" et te mettre en mode optimiste

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 84
    Par défaut
    Le problème si je me place en verrouillage optimiste est que (si j'ai bien compris) je dois au préalable modifier ma base pour ajouter un numéro de "version d'enregistrement" à chaque table :

    Truc (id, machin, chose) => Truc (id, machin, chose, noVersion)

    Et j'aimerai éviter d'avoir à toucher à la base elle même (je ne sais même pas si j'en ai le droit d'ailleurs)

  10. #10
    Membre chevronné Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Par défaut
    Oups pardon, j'ai dit une bêtise, je voulais dire "sans verrouillage" du tout

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 84
    Par défaut
    Ha oui la en effet ça marche mais il FAUT que je prévienne toutes éventualités...

    Car si le cas se présente (deux personnes, dans deux bureaux, se disent : "tient je vais faire une modif dans la base", et rendent la base incohérente...) c'est la cata !

    en plus c'est demandé par mon maitre de stage... accessoirement

  12. #12
    Membre chevronné Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Par défaut
    Tu crée une table contenant l'historique des connexions par exemple (qui, quand) et tu n'autorise applicativement qu'un seul utilisateur connecté. Le deuxième qui tente se prend un message lui demandant d'essayer plus tard, et éventuellement le nom de la personne connecté à ce moment là.

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 84
    Par défaut
    oui ça c'est une bonne idée...

    mais il reste toujours un problème :

    Si un utilisateur veut écrire dans la base à la main (exemple avec MySqlQueryBrowser pour une base MySql)

    rien ne l'en empèche...

    (ce smiley correspond tout à fait au comportement que je voudrait donner à ma base --> )

  14. #14
    Membre chevronné Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Par défaut
    Si tu pars du principe que n'importe qui peut accéder directement à la base de données pour faire des modifs à la main, seul le verrouillage pessimiste avec des locks sur chaque ligne que ton appli peut potentiellement modifier fonctionnera. En effet, même en optimiste, rien ne dit que l'utilisateur va correctement impacter le champ version ...

    Mais soyons réalistes, cette situation n'est pas acceptable dans le monde réel, c'est d'ailleurs le rôle de ton application de masquer la base de données. Les utilisateurs n'ont pas à avoir les identifiants de connexion à la BDD. Sinon à ce moment là, que se passe-t-il, (allons au bout des choses), si un utilisateur modifie à la main les fichiers de persistance du SGBD ?

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 84
    Par défaut
    C'est pas faux...

    En tous cas pour le blocage applicatif c'est maintenant fait et il est vrai que l'idée est bien de s'abstraire de la base en elle même (viva hibernate...)

    Donc je pense que je vais pouvoir faire passer aux autorités supérieur (mon maitre de stage) la contrainte "pas touche minouche !" sur la base...

    Quoi qu'il en soit, un grand merci pour ton aide précieuse et régulière

  16. #16
    Membre chevronné Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Par défaut
    bonne continuation

Discussions similaires

  1. date de modification d'une donnée dans la base
    Par Lucator dans le forum Contribuez
    Réponses: 21
    Dernier message: 25/07/2014, 23h17
  2. Activer de suite une modif dans la base de registre
    Par cincap dans le forum Débuter
    Réponses: 14
    Dernier message: 11/12/2009, 17h02
  3. Réponses: 4
    Dernier message: 11/01/2008, 12h18
  4. Problème lors d'une modification d'une base de données
    Par 4rocky4 dans le forum Modélisation
    Réponses: 2
    Dernier message: 08/01/2008, 16h04
  5. repérer les modifications aprés une action
    Par yazid308 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 06/09/2007, 11h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo