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

avec Java Discussion :

Utiliser ou non "synchronized" ?


Sujet :

avec Java

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut Utiliser ou non "synchronized" ?
    Bonjour à tous,
    J'ai une méthode java qui fait un traitement simple de lecture (" SELECT ..." ) et d'écriture ("UPDATE ...") dans une petite table (5 champs, une 10aine d'écriture max) et je voudrais rendre l'accès à cette table exclusif. C'est-à-dire, un utilisateur devra attendre que l'utilisateur précédant ait terminé le traitement dans cette table. J'ai pensé à 2 choses
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    
    1. Le mot clé "synchronized" dans la méthode.
    2. Pas de mot clé "synchronized" mais "SELECT ... FOR UPDATE OF ..." dans la requette à l'intérieur de la méthode.
    
    Quelle solution est plus efficace en terme de performances sachant qu'il s'agit d'une appli multi-utilisateur avec une centaine d'utilisateurs connectés simultanément.

    En existe-il d'autres?

    Merci d'avance!

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    pour moi aucune des deux. Je fairait plutot tout ma popotte dans une transaction serialisable. Et je laisserais la DB gérer les conflit, comme elle le fait bien en lancant une exception vers celui qui a perdu

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Merci pour ta réponse tchize_ mais mon problème est le suivant:
    Dans le code de cette méthode, j'ai d'abord, "SELECT ..." sur la table en question et ensuite "UPDATE ... " sur la même table et tant qu'un utilisateur n'a pas terminé ces 2 opération et commité ou rollbacké, je dois empêcher tout autre utilisateur non seulement d'écrire (UPDATE) mais aussi et SURTOUT de lire (SELECT) les données sur cette table en question.

    Or en regardant la doc d'Oracle (j'ai pas regardé pour d'autre BD), http://download.oracle.com/docs/cd/B...sist.htm#i5702 sous la rubrique "Comparison of Read Committed and Serializable Isolation", on remarque que le niveau d'isolation serializable n'empêche pas la lecture des données par l'utilisateur suivant alors qu'un utilisateur est en train d'exécuter le traitement. (Cf. "Writers block readers" dans la doc) C'est justement cela que je doit empêcher.

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Pourrais-tu expliquer un peu mieux ton besoin, car ça ne se fait pas de bloquer une table comme cela.

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    non mais ce n'est pas un problème, ce qui se passe avec oracle, c'est qu'il fait du locking optimiste mais il gère quand même ton cas.
    Oracle gère quand meme la situation. Imaginons le cas où ton user 2 lit alors que le use r1 a pas encore fini

    user 1: begin
    user 1: select
    user 2: begin
    user 2: select (les même rows)
    user 1: update
    user 2: update
    user 1: commit
    user 2: commit -> erreur: vous avez sélectionnez dans la tx des lignes qui on été modifiées par une autre transaction


    Bref oracle te lance l'erreur au commit avec le serializable, alors que beaucoup d'autres DB le feront au select. Pourquoi faire ça? Deux problème sont ainsi évités:

    user 1: begin
    user 1: select
    user 2: begin
    user 2: select (les même rows)
    user 1: update
    user 2: update
    user 1: rollback (pour une raison x ou y dépendant de l'application)
    user 2: commit -> ok
    Ainsi, pas de soucis pour le user 2, qui n'est pas influencé par le user 1, et état de la DB bien préservé.



    autre cas que vous évitez: les pertes de perfs si vous faites un select for update alors que vous n'etes pas sur de faire le update. Exemple: mettre à 0 toutes le password de tous les employés partis pour lequel l'account local est désactivé. Vous allez select for update tous les employés partis, puis un à un votre app va regarder si elle doit mettre le password à 0. Donc certains row seront locké inutilement. Orcale garanti que seul les row sur lequels vous avez vraiment fait un update entrent en compte.

    Bref, quand une DB vous garantis la sérialisabilité, faites lui confiance En fait, avec oracle, meme avec un select for update, les users ne se bloqueront pas mutuellement. Mais certains combinaison de transaction ne pourront pas être commitées. A vous de choper l'exception et de relancer la transaction (il existe même certains framework groovy qui servent à ça, répéter la transaction jusqu'à réussite :p).
    A noter qu'avec le serializable vous n'aurez ni dirty read, ni phatom read, donc aucun risque de mélange des transaction, vous êtes en sécurité, toutt ce que vous risquez c'est l'exception au commit

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