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 :

Concurrence d'insertion de données


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur

    Homme Profil pro
    Geek entrepreneur
    Inscrit en
    Novembre 2004
    Messages
    1 224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Geek entrepreneur

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 224
    Par défaut Concurrence d'insertion de données
    Bonjour,

    Le problème que je vais décrire n'est pas spécifique hibernate, j'aurais pu poster dans une autre section.

    J'ai un souci de concurrence d'insertion dans une base de données.
    J'ai 3 applis identiques (un cluster) qui insérent chacune dans une table des éléments. La clé est fonctionnelle, ce n'est pas un id que l'on peut obtenir avec un auto increment ou une séquence.
    Par exemple j'insère un valeur "valeur1" qui est une clé.

    Il est possible que les 3 applis insérent la même donnée, du coup on peut tomber sur des violations de contraintes même si chacune fait un test d'existence (Il subsistera toujours un court laps de temps entre le test et l'insertion).

    Quelle est l'astuce la plus propre pour ce cas de figure ?

    - attraper une exception dans le service qui utilise le DAO et passer l'erreur sous silence ? (Pas terrible comme gestion d'erreur)
    - autre ?

  2. #2
    Membre chevronné
    Profil pro
    Développeur Java
    Inscrit en
    Novembre 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2007
    Messages : 301
    Par défaut
    Je n'ai jamais rencontré ce problème par contre il y a une section de la documentation officiel sur ce point et elle propose des solutions : http://www.hibernate.org/hib_docs/v3...nsactions.html.

    Dans ton cas, pourquoi tu ne fais pas tout simplement un saveOrUpdate() ?

    Après, il faut peut être aussi regarder du côté des niveaux d'isolation des transactions.

  3. #3
    Rédacteur

    Homme Profil pro
    Geek entrepreneur
    Inscrit en
    Novembre 2004
    Messages
    1 224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Geek entrepreneur

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 224
    Par défaut
    Citation Envoyé par darkxan Voir le message
    Je n'ai jamais rencontré ce problème par contre il y a une section de la documentation officiel sur ce point et elle propose des solutions : http://www.hibernate.org/hib_docs/v3...nsactions.html.

    Dans ton cas, pourquoi tu ne fais pas tout simplement un saveOrUpdate() ?

    Après, il faut peut être aussi regarder du côté des niveaux d'isolation des transactions.
    Juste pour préciser par rapport à cette réponse :

    le saveOrUpdate est basé sur le même principe, je teste l'existence et j'insère ou j'update en fonction du résultat. C'est d'ailleurs ce que j'utilise mais ca ne prévient pas ce type de problème. J'utilise correctement des transactions mais malheureusement dans une transaction différente j'attaque la même table sur des clés identiques et comme il n'y a pas de lock de table, ca casse.



    En tout cas pour l'instant je ne passe pas ce post en résolu car c'est pour moi le fait de catcher les exceptions et recommencer sans arret est une solution de contournement assez moche.

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par hugo123 Voir le message
    Bonjour,

    Le problème que je vais décrire n'est pas spécifique hibernate, j'aurais pu poster dans une autre section.

    J'ai un souci de concurrence d'insertion dans une base de données.
    J'ai 3 applis identiques (un cluster) qui insérent chacune dans une table des éléments. La clé est fonctionnelle, ce n'est pas un id que l'on peut obtenir avec un auto increment ou une séquence.
    Par exemple j'insère un valeur "valeur1" qui est une clé.

    Il est possible que les 3 applis insérent la même donnée, du coup on peut tomber sur des violations de contraintes même si chacune fait un test d'existence (Il subsistera toujours un court laps de temps entre le test et l'insertion).

    Quelle est l'astuce la plus propre pour ce cas de figure ?

    - attraper une exception dans le service qui utilise le DAO et passer l'erreur sous silence ? (Pas terrible comme gestion d'erreur)
    - autre ?
    autre :

    … pessimistic locking sur la table… (le row exclusive mode de PostgreSQL…)
    pas géré par Hibernate (il gère le pessimictic locking sur le record…), faudra passer par du SQL natif donc dépendant du RDBMS…

    schématiquement:

    processing loop
    get data to process
    prepare POJO to insert
    begin
    lock table in row exclusive mode
    select record on criteria
    if not found then
    insert POJO
    endif
    commit
    end processing loop


    et que le block begin/commit prenne le moins de temps possible…
    pour que la table soit verrouillée le moins de temps possible…



    mais le filtrage des exceptions peut très bien faire l'affaire aussi…

  5. #5
    Rédacteur

    Homme Profil pro
    Geek entrepreneur
    Inscrit en
    Novembre 2004
    Messages
    1 224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Geek entrepreneur

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 224
    Par défaut
    Après test, la solution avec lock de table est problématique. Hibernate ne gère pas de native sql autre que des select, les deux seules méthodes de SQLQuery sont uniqueResult et list (executeUpdate lance une unsupportedException).

    Du coup, pas possible de faire le lock par cette méthode.
    Le fait d'utiliser la connection directement en la récupérant de la sessionfactory n'est pas bon non plus puisqu'on se désolidarise de la transaction hibernate et on tombe sur l'erreur :
    A LOCK TABLE command is not allowed outside the scope of a transaction on table

    Du coup, ce sera la méthode avec exception, c'est moche mais bon...

Discussions similaires

  1. problème d'insertion de données
    Par Falgan dans le forum ASP
    Réponses: 2
    Dernier message: 06/04/2004, 09h29
  2. [Interbase 7] Problème d'insertion de données
    Par Tuscelan dans le forum InterBase
    Réponses: 12
    Dernier message: 19/11/2003, 22h58
  3. [EJB] Accès concurrents à la base de données
    Par cameleon2002 dans le forum Java EE
    Réponses: 10
    Dernier message: 23/09/2003, 11h31
  4. insertion de données
    Par m-l dans le forum SQL
    Réponses: 9
    Dernier message: 25/07/2003, 13h59
  5. [Postgresql] pb lors d'insertion de données
    Par bob20000 dans le forum Requêtes
    Réponses: 8
    Dernier message: 04/11/2002, 15h33

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