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

PL/SQL Oracle Discussion :

Procédure détection Deadlock / insertion impossible


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    117
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 117
    Par défaut Procédure détection Deadlock / insertion impossible
    Bonjour,
    J'ai créé une procédure qui permet d'enregistrer des informations concernant les interbloquages dans une base de données.
    Je créé tout d'abord une table pour stocker mes informations:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    create table report_deadlock(
    lock_date VARCHAR2(30),
    wa_waiting_session NUMBER,
    wa_username VARCHAR2(30),
    wa_lock_type VARCHAR2(26),
    wa_sql_id VARCHAR2(13),
    wa_sql_text VARCHAR2(1000),
    ho_holding_session NUMBER,
    ho_username VARCHAR2(30),
    ho_lock_type VARCHAR2(26),
    ho_sql_id VARCHAR2(13),
    ho_sql_text VARCHAR2(1000));
    Ensuite je crée une procédure autonome, cette procédure doit enregistrer les informations de l'interbloquage dans une table:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    CREATE OR REPLACE PROCEDURE insert_report_deadlock IS
    PRAGMA AUTONOMOUS_TRANSACTION;
    BEGIN
    INSERT INTO report_deadlock(lock_date, wa_waiting_session, wa_username, wa_lock_type, wa_sql_id, wa_sql_text, ho_holding_session, ho_username, ho_lock_type, ho_sql_id, ho_sql_text) 
    select to_char(sysdate,'DD-MM-YYYY HH24:MI:SS'), wa_dba_waiters.WAITING_SESSION, wa_v$session.USERNAME, wa_dba_waiters.LOCK_TYPE, wa_v$sqlarea.SQL_ID, wa_v$sqlarea.sql_text, ho_dba_waiters.HOLDING_SESSION, ho_v$session.USERNAME, ho_dba_waiters.LOCK_TYPE, ho_v$sqlarea.SQL_ID, ho_v$sqlarea.sql_text
    from dba_waiters wa_dba_waiters, v$session wa_v$session, v$sqlarea wa_v$sqlarea, dba_waiters ho_dba_waiters, v$session ho_v$session, v$sqlarea ho_v$sqlarea
    where wa_dba_waiters.waiting_session=wa_v$session.sid
    and wa_v$session.sql_address=wa_v$sqlarea.address
    and ho_dba_waiters.holding_session=ho_v$session.sid
    and ho_v$session.sql_address=ho_v$sqlarea.address;
     
    COMMIT;
    END insert_report_deadlock;
    Puis je crée un trigger
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CREATE OR REPLACE TRIGGER report_deadlock_trigger
    AFTER SERVERERROR
    ON DATABASE
    BEGIN
    IF (IS_SERVERERROR (60)) THEN
    sys.insert_report_deadlock;
    END IF;
    END report_deadlock_trigger;
    J'ai vérifié en provoquant un interbloquage et en exécutant mon "INSERT" qui est dans la procédure, les valeurs sont bien insérées dans la tables:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    INSERT INTO report_deadlock(lock_date, wa_waiting_session, wa_username, wa_lock_type, wa_sql_id, wa_sql_text, ho_holding_session, ho_username, ho_lock_type, ho_sql_id, ho_sql_text) 
    select to_char(sysdate,'DD-MM-YYYY HH24:MI:SS'), wa_dba_waiters.WAITING_SESSION, wa_v$session.USERNAME, wa_dba_waiters.LOCK_TYPE, wa_v$sqlarea.SQL_ID, wa_v$sqlarea.sql_text, ho_dba_waiters.HOLDING_SESSION, ho_v$session.USERNAME, ho_dba_waiters.LOCK_TYPE, ho_v$sqlarea.SQL_ID, ho_v$sqlarea.sql_text
    from dba_waiters wa_dba_waiters, v$session wa_v$session, v$sqlarea wa_v$sqlarea, dba_waiters ho_dba_waiters, v$session ho_v$session, v$sqlarea ho_v$sqlarea
    where wa_dba_waiters.waiting_session=wa_v$session.sid
    and wa_v$session.sql_address=wa_v$sqlarea.address
    and ho_dba_waiters.holding_session=ho_v$session.sid
    and ho_v$session.sql_address=ho_v$sqlarea.address;
    J'ai vérifier que le trigger se déclenche bien lorsque je provoque un interbloquage en modifiant le corps de ma procédure par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    insert into test(col1) values ('bibaboomm');
    Je retrouve bien ma valeur insérée. Pourquoi es ce que je n'ai rien dans ma table "report_deadlock" lorsque je laisse le trigger se déclencher pour logger les informations sur les interbloquages????

  2. #2
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Je peur que l'information n'est plus disponible!
    Ajoutez
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    dbms_output.put_line('Lignes inserées = '||To_Char(SQL%ROWCOUNT));
    dans ta procédure après l'insert et avant le commit.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    117
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 117
    Par défaut
    Ben malheureusement je pense que si.

    Je provoque un interbloquage.
    Tout de suite je lance ma requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select to_char(sysdate,'DD-MM-YYYY HH24:MI:SS'), wa_dba_waiters.WAITING_SESSION, wa_v$session.USERNAME, wa_dba_waiters.LOCK_TYPE, wa_v$sqlarea.SQL_ID, wa_v$sqlarea.sql_text, ho_dba_waiters.HOLDING_SESSION, ho_v$session.USERNAME, ho_dba_waiters.LOCK_TYPE, ho_v$sqlarea.SQL_ID, ho_v$sqlarea.sql_text
    from dba_waiters wa_dba_waiters, v$session wa_v$session, v$sqlarea wa_v$sqlarea, dba_waiters ho_dba_waiters, v$session ho_v$session, v$sqlarea ho_v$sqlarea
    where wa_dba_waiters.waiting_session=wa_v$session.sid
    and wa_v$session.sql_address=wa_v$sqlarea.address
    and ho_dba_waiters.holding_session=ho_v$session.sid
    and ho_v$session.sql_address=ho_v$sqlarea.address;
    Elle me retourne les bonnes valeurs.
    J'ai exécuté cette requête 15 minutes après elle me retourne toujours les bons résultats.
    Je me suis dis peut être qu'il faut un peu de temps (quelques secondes pour que l'infos soit disponible j'ai donc rajouté un "dbms.sleep(60)" meme problème rien n'ai enregistré dans ma table.
    Si pendant ces 15 minutes je lance à la main l'insertion:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    INSERT INTO report_deadlock(lock_date, wa_waiting_session, wa_username, wa_lock_type, wa_sql_id, wa_sql_text, ho_holding_session, ho_username, ho_lock_type, ho_sql_id, ho_sql_text) 
    select to_char(sysdate,'DD-MM-YYYY HH24:MI:SS'), wa_dba_waiters.WAITING_SESSION, wa_v$session.USERNAME, wa_dba_waiters.LOCK_TYPE, wa_v$sqlarea.SQL_ID, wa_v$sqlarea.sql_text, ho_dba_waiters.HOLDING_SESSION, ho_v$session.USERNAME, ho_dba_waiters.LOCK_TYPE, ho_v$sqlarea.SQL_ID, ho_v$sqlarea.sql_text
    from dba_waiters wa_dba_waiters, v$session wa_v$session, v$sqlarea wa_v$sqlarea, dba_waiters ho_dba_waiters, v$session ho_v$session, v$sqlarea ho_v$sqlarea
    where wa_dba_waiters.waiting_session=wa_v$session.sid
    and wa_v$session.sql_address=wa_v$sqlarea.address
    and ho_dba_waiters.holding_session=ho_v$session.sid
    and ho_v$session.sql_address=ho_v$sqlarea.address;
    Ma ligne est bien insérée, je ne comprends pas!!!

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    117
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 117
    Par défaut
    En faite si je provoque le deadlock et que j'exécute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    begin
    sys.insert_report_deadlock;
    end;
    ca marche, alors que si je laisse le trigger se déclencher ca ne marche pas.
    Mais je sais que le trigger et bon car si je change le corps de la procédure ca marche.

    Bien bizzar ....

  5. #5
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Sur une base Oracle 10.2.0.4.0 ou Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production, ton select:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT to_char(sysdate,'DD-MM-YYYY HH24:MI:SS'), wa_dba_waiters.WAITING_SESSION, wa_v$session.USERNAME, wa_dba_waiters.LOCK_TYPE, wa_v$sqlarea.SQL_ID, wa_v$sqlarea.sql_text, ho_dba_waiters.HOLDING_SESSION, ho_v$session.USERNAME, ho_dba_waiters.LOCK_TYPE, ho_v$sqlarea.SQL_ID, ho_v$sqlarea.sql_text
    FROM dba_waiters wa_dba_waiters, v$session wa_v$session, v$sqlarea wa_v$sqlarea, dba_waiters ho_dba_waiters, v$session ho_v$session, v$sqlarea ho_v$sqlarea
    WHERE wa_dba_waiters.waiting_session=wa_v$session.sid
    AND wa_v$session.sql_address=wa_v$sqlarea.address
    AND ho_dba_waiters.holding_session=ho_v$session.sid
    AND ho_v$session.sql_address=ho_v$sqlarea.address
    ne me ramène rien. Si je le bidouille j'ai l'enregistrement.
    Mais essayez d'ajouter la ligne dans la procédure comme j'ai vous le dit. Quelle est le résultat ?

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    117
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 117
    Par défaut
    Si je lance apres avoir provoqué un deadlock:
    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
     
    CREATE OR REPLACE PROCEDURE insert_report_deadlock IS
    PRAGMA AUTONOMOUS_TRANSACTION;
    BEGIN
    INSERT INTO report_deadlock(lock_date, wa_waiting_session, wa_username, wa_lock_type, wa_sql_id, wa_sql_text, ho_holding_session, ho_username, ho_lock_type, ho_sql_id, ho_sql_text) 
    select to_char(sysdate,'DD-MM-YYYY HH24:MI:SS'), wa_dba_waiters.WAITING_SESSION, wa_v$session.USERNAME, wa_dba_waiters.LOCK_TYPE, wa_v$sqlarea.SQL_ID, wa_v$sqlarea.sql_text, ho_dba_waiters.HOLDING_SESSION, ho_v$session.USERNAME, ho_dba_waiters.LOCK_TYPE, ho_v$sqlarea.SQL_ID, ho_v$sqlarea.sql_text
    from dba_waiters wa_dba_waiters, v$session wa_v$session, v$sqlarea wa_v$sqlarea, dba_waiters ho_dba_waiters, v$session ho_v$session, v$sqlarea ho_v$sqlarea
    where wa_dba_waiters.waiting_session=wa_v$session.sid
    and wa_v$session.sql_address=wa_v$sqlarea.address
    and ho_dba_waiters.holding_session=ho_v$session.sid
    and ho_v$session.sql_address=ho_v$sqlarea.address;
    dbms_output.put_line('Lignes inserées = '||To_Char(SQL%ROWCOUNT));
    COMMIT;
    END insert_report_deadlock;
    /
    set serveroutput on
    begin
    sys.insert_report_deadlock;
    end;
    Ca me retourne "Lignes inser¿es = 1";
    La procédure fonctionne, le problème c'est que si elle est déclenchée par le trigger, elle ne fonctionne pas.
    Il y a quelque chose qui bloque ma procédure dans le trigger mais je ne vois pas quoi. Si je remplace cette procédure par une banale ca fonctionne donc ca viens bien du faite que j'utilise cette procédure dans ce trigger.

Discussions similaires

  1. Réponses: 2
    Dernier message: 10/04/2014, 17h26
  2. Code requete INSERT impossible VB2005
    Par hellspawn_ludo dans le forum Accès aux données
    Réponses: 18
    Dernier message: 11/03/2007, 15h41
  3. Procédure stocké et insertion de données
    Par yancimer dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 29/08/2006, 17h33
  4. Insertion impossible a cause de l'IDENTITY_INSERT
    Par oli_carbo dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 22/03/2006, 14h24
  5. Réponses: 10
    Dernier message: 22/11/2004, 22h37

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