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

Oracle Discussion :

[PL/SQL]Procédure qui ne se finit pas...


Sujet :

Oracle

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 169
    Points : 80
    Points
    80
    Par défaut [PL/SQL]Procédure qui ne se finit pas...
    Bonjour,

    j'ai créé une procédure qui fait des mises à jours sur différentes bases oracle via des dblink.
    A la fin de ma procédure un COMMIT valide ma transaction.
    Le problème que je me pose est le suivant:

    -dans le cas où un verrou est posé sur un enregistrement que je vais mettre à jour, que va-t-il se passer?

    Voici un exemple:

    - je mets à jour sur la BDD 1
    - je mets à jour sur la BDD 2
    - je mets à jour sur la BDD 3
    - je Commit.

    Maintenant, un verrou est posé sur l'enregistrement de ma BDD 3
    - je mets à jour sur la BDD 1
    - je mets à jour sur la BDD 2
    - j'attends la fin du verrou qui a été posé pour pouvoir continuer...

    Mais le problème est que de ce fait je pose moi-même des verrous sur BDD1 et BDD2.

    Y a t il possibiliter de paramétrer un timeout sur la procédure, ou bien de récupérer une exception dans ma procédure?

    Je vous remercie de votre aide.

    Anthony.

  2. #2
    Membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2004
    Messages : 81
    Points : 69
    Points
    69
    Par défaut
    qu'est ec que vous voulez dir par verrous?
    Oracle c'est pas des Miracles

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 169
    Points : 80
    Points
    80
    Par défaut
    En fait pour moi un verrou c'est un lock qui empêche la mise à jour d'un enregistrement si le commit de la précédente mise à jour n'a pas été effectué.

  4. #4
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    Il vous faut poser les verrous par un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT xxx
     FOR UPDATE
    NOWAIT;
    Dans ce cas, si l'enregistrement est déjà locké, la procédure n'attend pas la libération de l'enregistrement et déclenche une exception.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 169
    Points : 80
    Points
    80
    Par défaut
    Vous pouvez être un peu plus explicite svp?

    Est ce que je peux intégrer directement cette fonctionnalité dans ma procédure?

    Dsl, je n'ai pas bien compris l'exemple.

    Merci bcp.

  6. #6
    Membre confirmé

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    487
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 487
    Points : 455
    Points
    455
    Par défaut
    vous pouvez aussi tuer les sessions qui posent des verrous.Que ce soient les votres ou celles de vos voisins (evidement avec les droits appropriés).

    voici le genre de requêtes que j'utilise pour cela
    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
    22
    23
     
    select 'alter system kill session '|| ''''||
             s.sid ||
             ','||
             s.serial# ||
             ''';'
    from v$lock l,
      v$lock d,
      v$session s,
      v$session b,
      v$process p,
      v$transaction t,
      sys.dba_objects o,
      v$open_cursor c
    where l.sid = s.sid
      and o.object_id (+) = l.id1
      and c.hash_value (+) = s.sql_hash_value
      and c.address (+) = s.sql_address
      and s.paddr = p.addr
      and d.kaddr (+) = s.lockwait
      and d.id2 = t.xidsqn (+)
      and b.taddr (+) = t.addr
      and l.type = 'TM';

  7. #7
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    L'exemple donné permet de verrouiller explicitement l'enregistrement AVANT d'effectuer la mise à jour.
    En effet, en temps normal, le verrou n'est posé qu'entre le moment de l'update (t1) et le moment de fin de transaction (i.e. commit ou rollback) (t2).

    Pour éviter de se retrouver en attente de fin de transaction, vous pouvez, avant d'effectuer l'update, vous assuré qu'il est libre de tout verrou en posant un verrou sans pour autant modifier l'enregistrement.

    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
    22
    23
    24
    25
    26
     
    BEGIN
       ... /* début de la procédure */
       /* On doit mettre à jour la ligne de la table MATABLE dont le NUM = 10
       BEGIN
          SELECT * FROM MATABLE WHERE Num= 10 FOR UPDATE NOWAIT;
          /* à partir de maintenant, la ligne est verrouillée */
     
          ...
     
          UPDATE MATABLE
               SET ...
            WHERE Num = 10;
     
          ...
     
     
         COMMIT;
          /* Il faut obligatoirement libérer l'enregistrement */
       EXCEPTIONS
        WHEN OTHERS THEN
           IF SQLCode  = 54 THEN
             /* L'enregistrement était déjà verrouillé*/
              ...
           END IF;
       END;

  8. #8
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    Voila une lien intéressant : http://asktom.oracle.com/pls/ask/f?p=4950:8:5915454283198116693::NO::F4950_P8_DISPLAYID,F4950_P8_CRITERIA:4515126525609

    Le but étant d'essayer de réserver 3 fois l'enregistrement qu'on souhaite mettre à jour et de retourner une erreur si une exception de lock se déclenche.

    Voila une fonction que tu peux adapter qui retourne FALSE si la ligne p_id est réservée dans matable :

    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
    CREATE OR REPLACE FUNCTION check_id (p_id INTEGER) RETURN BOOLEAN AS
        resource_busy   EXCEPTION;
        PRAGMA EXCEPTION_INIT( resource_busy, -54 );
        success BOOLEAN := False;
        dummy matable%ROWTYPE;
    BEGIN
     
      SELECT id, col2
        INTO dummy
        FROM matable 
       WHERE id = p_id 
       FOR UPDATE NOWAIT;
     
      RETURN TRUE;
     
      EXCEPTION 
        WHEN resource_busy then
          RETURN FALSE;
    END;
    /

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 169
    Points : 80
    Points
    80
    Par défaut
    Merci à vous tous pour votre aide.

    Mon problème est en effet résolu.

    Merci.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Procédure qui ne "s'arrête" pas
    Par kmgaryx dans le forum Développement
    Réponses: 1
    Dernier message: 27/03/2012, 09h16
  2. [PL/SQL]Procédure qui se compile avec des erreurs
    Par yoann7 dans le forum PL/SQL
    Réponses: 12
    Dernier message: 17/03/2009, 11h09
  3. [MySQL] requete sql qui ne s'exécute pas
    Par anto48_4 dans le forum PHP & Base de données
    Réponses: 15
    Dernier message: 16/03/2006, 09h12
  4. [PL/SQL] Trigger qui appelle une procédure
    Par alex6891 dans le forum Oracle
    Réponses: 5
    Dernier message: 19/01/2006, 09h01
  5. [PL/SQL] requete qui marche mais pas dans un cursor
    Par victor.ward dans le forum Langage SQL
    Réponses: 3
    Dernier message: 09/09/2005, 22h21

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