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

JDBC Java Discussion :

Gestion d’accès à la base de données en utilisant Hibernate


Sujet :

JDBC Java

  1. #1
    Membre régulier Avatar de Palsajicoco
    Étudiant
    Inscrit en
    Février 2007
    Messages
    229
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 229
    Points : 84
    Points
    84
    Par défaut Gestion d’accès à la base de données en utilisant Hibernate
    Salut,

    Je suis entrain d’accéder a la base de donné a partir de hibernate. Ma méthode fait une requête sur deux équipements connecté entre eux. Dans un multithreading, les deux équipements sont exécutés en même temps et créent une connection physique. Afin d'enregistrer cette connection dans la base de donnée, je fait une requête avant pour savoir si cette connection existe déjà ou non. ce qui doit être le cas si un élément enregistre la connectin avant l'autre. Du coup, j'arrive toujour au stade ou les deux équipements dans le multithreading accèdent au meme temps en milliseconde a faire la requête pour savoir si il y a une connection deja ou non. du coup ils utilisent tout les deux la méthode save de Hibernate pour enregistrer .. et la j'ai un problème de duplicated key.

    Voici la console:
    12:59:07,312 DEBUG SQL:111 - Requête SQL pour vérifier si une connection existe dans la base de donnée pour l’équipement 1
    12:59:07,312 DEBUG SQL:111 - Requête SQL pour vérifier si une connection existe dans la base de donnée pour l’équipement 2
    12:59:09,312 DEBUG SQL:111 - Save de connection pour l’équipement 1
    12:59:09,312 DEBUG SQL:111 - Save de connection pour l’équipement 2
    12:59:11,609 ERROR JDBCExceptionReporter:234 - Duplicate entry '3066-3069' for key 2
    Key 2 c'est l'indexe unique de la connection. (couple de ports des deux coté de chaque équipement.).

    Pour resumer. chaque equipement doit verifier si un centree existe deja dans la DB, si elle existe il fait merge de hiberate, sinon il fait save. ducoup il fait toujours save puisque ils verifient au meme temps avec la milliseconde, Du coup aucun equipement n'a lachance de trouver une entree deja existante.

    J'ai essayé de contourner le problème avec un synchronized .. mais ça ne change rien. Voici le code appliqué dans le thread pour chaque équipement et qui cause le problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if (localNE.getNetworkElementId() == (getNetworkElement().getNetworkElementId())) { 
                        PhysicalConnection physicalConnection = localPersistentPtp.radioLink(remotePersistentPtp);
                        logger.debug("Physical Connection should be created: " + getNetworkElement() + " - " + remoteNE);
                        //logger.debug("Physical Connection should be created: " + physicalConnection.getPtpByPtpIdAend().getPtpId() + " - " + physicalConnection.getPtpByPtpIdZend().getPtpId());
                        phyConns.add(physicalConnection);
     
                        phyConnHelp.insertOrUpdate(physicalConnection);
     
                        logger.debug("Basic physical connections (no protection) for: " + getNetworkElement().toString() + " : " + physicalConnection);
                    }
    La méthode insert or update de hibernate fait une requête sur l'objet, si il existe elle fait merge, sinon save. c'est les fonctions prédéfinies de Hibernate.

    J’espère pouvoir contourner ce problème. Merci d'avance.

  2. #2
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Points : 4 792
    Points
    4 792
    Par défaut
    Il y a un forum hibernate ...

  3. #3
    Membre régulier Avatar de Palsajicoco
    Étudiant
    Inscrit en
    Février 2007
    Messages
    229
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 229
    Points : 84
    Points
    84
    Par défaut
    Ce n'est pas du tout hibernate mon probleme ...
    J'aurai apprécié une réponse utile par contre .. pas faire le job d'un admin

  4. #4
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Points : 4 792
    Points
    4 792
    Par défaut
    Bon, si j'ai bien compris, c'est la BD qui refuse, à juste titre, d'avoir deux fois '3066-3069' dans la clé d'une table.

    Comme on travaille avec des threads, on peut imaginer créer un objet synchronisé
    qui sert de sémaphore avec le scénario suivant :

    1) un thread accède d'abord à l'objet et donc le verrouille
    2) il utilise la méthode insert or update de hibernate (que je ne connais pas)
    3) il déverrouille l'objet

    Cela oblige chaque thread à attendre que l'autre ai fini ...

    Je continue à ne pas voir le rapport avec JDBC

  5. #5
    Membre régulier Avatar de Palsajicoco
    Étudiant
    Inscrit en
    Février 2007
    Messages
    229
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 229
    Points : 84
    Points
    84
    Par défaut
    Merci pour la proposition,

    J'ai essayé plusieurs fois avec semaphore, mais je voulais verrouiller juste l'eoject a enregistrer ou modifier.

    J'ai fait une nouvelle classe qui me retourne une semaphore pour chaque object.

    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
    17
    18
    19
    20
    21
    package com.oghmasys.nomad.monitoring.probeset;
     
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.Semaphore;
     
    import com.oghmasys.nomad.mdblib.mappingclass.PhysicalConnection;
     
     
    public class SemaphoreFactory {
     
    	public static Semaphore getSemaphore(PhysicalConnection physicalConnection){
    		Map<Object, Semaphore> semaphores = new HashMap<Object, Semaphore>();
    	    if ( !semaphores.containsKey(physicalConnection) ) {
    	        semaphores.put(physicalConnection, new Semaphore(3));
    	    }
    	    return semaphores.get(physicalConnection);
    	}
     
     
    }
    Puis dans mon thread je fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                  Semaphore semaphore = SemaphoreFactory.getSemaphore(physicalConnection);
                            semaphore.acquire(); // Blocks here until the Semaphore is free
                            logger.debug("semaphore" + semaphore);
                            phyConnHelp.insertOrUpdate(physicalConnection);
                            semaphore.release(); // Other Threads might now acquire the semaphore for this physical connection
    Ca ne semble pas marcher vue que j'ai toujours la meme erreur.

  6. #6
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Points : 4 792
    Points
    4 792
    Par défaut
    ou là là c'est bien compliqué ce que tu as fait là.

    Je pensais à quelque chose de plus simple : faire une méthode "synchronized" du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class InsertionSynchro{
     
        public synchronized void majPhysicalConnection() {
            ... mon code de mise à jour / insertion  ...
            NotifyAll();
        }
     
    }
    L'idée c'est que pour faire un insert / update, on doit passer par cette méthode majPhysicalConnection
    qui est bloquée si un Thread y accède déjà
    et qui se libère automatiquement à la fin

    http://download.oracle.com/javase/tu.../locksync.html

    (tu peux trouver un topo complet sur la synchro ici)

  7. #7
    Membre régulier Avatar de Palsajicoco
    Étudiant
    Inscrit en
    Février 2007
    Messages
    229
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 229
    Points : 84
    Points
    84
    Par défaut
    Merci pour la réponse,

    Le problème ne sera pas résolu avec un simple synchronized parce que chaque thread a sa session hibernate a lui donc sysnchronized ne pourra rien faire.

    Je devrai avoir une sémaphore pour contrôler un bloc de code dans le thread, pour qu'il soit utilisé qu'une seule fois dans l’exécution des threads quelque soit la session hibernate.

  8. #8
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Points : 4 792
    Points
    4 792
    Par défaut
    Justement,

    Si tous les thread hybernate doivent passer par cette seule méthode synchronized
    alors ils seront obligés de "faire la queue" devant le "guichet"
    même s'ils ont chacun leurs propres connexions

Discussions similaires

  1. Réponses: 5
    Dernier message: 10/06/2010, 17h45
  2. Insertion dans la base de donnée en utilisant Hibernate
    Par malek21 dans le forum Hibernate
    Réponses: 0
    Dernier message: 29/04/2010, 22h42
  3. [MySQL] Systeme de gestion des droit d'accès par base de donnée
    Par megacool dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 04/01/2009, 12h53
  4. Gestion des accès à une base de données
    Par white_tiger dans le forum Sécurité
    Réponses: 7
    Dernier message: 07/02/2007, 01h39

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