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

SQL Oracle Discussion :

[Oracle 10] Verrou sur ligne


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 224
    Par défaut [Oracle 10] Verrou sur ligne
    Bonjour,

    J'ai une interface utilisateur qui permet de faire des modifications sur un enregistrement précis en base (avec un update).
    L'utilisateur sélectionne la ligne à modifier, une IHM se lance en renseignant les valeurs de la ligne dans un formulaire, un fois les modifications apportées (apres qques minutes), l'utilisateur les sauvegarde et donc un update est fait en base.

    Le problème est que je peux avoir plusieurs utilisateurs qui décident de mettre à jour le même enregistrement au même moment. Je voudrais donc interdire à un utilisateur de lancer l'IHM de modification quand un autre utilisateur est deja en train de le modifier.

    J'ai entendu parlé des verrous (lock) mais d'après ce que j'ai compris, ceux ci sont utilisés pour une transaction (SELECT, UPDATE, INSERT) , alors que moi je voudrais plus le faire pour une "session" (l'utilisateur dans l'IHM).

    --
    En resumé, je veux locker une ligne precise pour un temps indeterminé pour un utilisateur qui peut faire ce qu'il veut dessus (UPDATE, DELETE).
    Mais je veux que cette ligne soit accessible en lecture par les autres utilisateurs (SELECT).
    Les verrous oracle sont ils adaptés à cela?

    Ou faut il que je fasse une gestion manuelle en ajoutant une colonne LOCK_ a ma table contenant l'ID de l'utilisateur pouvant modifier la table et en esperant que mon utilisateur quitte l'appli proprement pour que je puisse delocker ma table à la main (remettre le champs LOCK_ à NULL).

  2. #2
    Membre émérite Avatar de philcero
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Septembre 2007
    Messages
    528
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2007
    Messages : 528
    Par défaut
    Effectue pour cela un SELECT .... FOR UPDATE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT id, nom 
    FROM employes 
    WHERE type='glandeur'
    ORDER BY nom;
    devient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT id, nom 
    FROM employes 
    WHERE type='glandeur'
    FOR UPDATE
    ORDER BY nom;
    Ainsi les lignes ciblées sont accessibles en read only pour les autre sessions jusqu'à ce que tu fasses un COMMIT. Par contre regarde la documentation "SQL*Reference->SELECT" pour les restrictions d'utilisation de la clause "FOR UPDATE".

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 224
    Par défaut
    EDIT: Merci philcero c'est exactement ce que je cherchais.

    Mais il y a un petit problème,

    Ptit code de test:
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #define OTL_ORA9I  // Compile OTL 4.0/OCI10gR2 // Base de recette sous oracle 9i
    #define OTL_STL // Handles the STL
    #define OTL_ANSI_CPP // Turn on ANSI C++ typecasts
    #include <otlv4.h> // include the OTL 4.0 header file
     
    int main(){
     
        otl_connect db;
        otl_connect::otl_initialize();
        db.rlogon("***");
        int i;
        try {
                otl_stream selectCalendars (50, "select NAME_, IDCALENDAR_ from CALENDAR FOR UPDATE order by NAME_ ASC", db);
     
            int idcalendar;
            char name[30];
            while (!selectCalendars.eof()) {
                selectCalendars >> name >> idcalendar;
                std::cout << "Calendar: " << name << ":id:" << idcalendar << std::endl;
            }
            std::cout << "Continue" << std::endl;
     
            std::cin  >> i;
     
            otl_stream update (50, "UPDATE CALENDAR SET NAME_ = :f1<char[30]> WHERE NAME_ = :f1", db);
            update.set_commit(0);
            update << name;
            db.commit();
        }
        catch (otl_exception &e) {
            std::cout << e.msg << std::endl;
        }
        db.logoff();
     
        std::cout << "Finish" << std::endl;
        std::cin  >> i;
        return 0;
    }

    i je lance 2 fois ce programmes, le premier lancer fait le select et le deuxieme attend "dans le vide" que je fasse mon update pour faire son select.
    Le pb c'est que j'aimerais avoir un retour me disant, hop hop hop la table est locker, que voullez vous faire, attendre ou quitter.


    EDIT: pifor: votre lien semble en effet traiter de mon sujet, je le lis et je reviens vers vous.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 224
    Par défaut
    NOWAIT est mon ami

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #define OTL_ORA9I  // Compile OTL 4.0/OCI10gR2
    #define OTL_STL // Handles the STL
    #define OTL_ANSI_CPP // Turn on ANSI C++ typecasts
    #include <otlv4.h> // include the OTL 4.0 header file
    
    int main(){
    
        otl_connect db;
        otl_connect::otl_initialize();
        db.rlogon("****");
        int i;
        try {
                otl_stream selectCalendars (50, "select NAME_, IDCALENDAR_ from CALENDAR FOR UPDATE NOWAIT order by NAME_ ASC", db);
            
            int idcalendar;
            char name[30];
            while (!selectCalendars.eof()) {
                selectCalendars >> name >> idcalendar;
                std::cout << "Calendar: " << name << ":id:" << idcalendar << std::endl;
            }
            std::cout << "Continue" << std::endl;
    
            std::cin  >> i;
            
            otl_stream update (50, "UPDATE CALENDAR SET NAME_ = :f1<char[30]> WHERE NAME_ = :f1", db);
            update.set_commit(0);
            update << name;
            db.commit();
        }
        catch (otl_exception &e) {
            if (e.code == 54) { // Code d'erreur oracle signalant que la ressource est deja prise
                std::cout << "Ressource is being modified by someone else, try again later";
            } else {
            std::cout << e.msg << std::endl;
            }
        }
        db.logoff();
    
        std::cout << "Finish" << std::endl;
        std::cin  >> i;
        return 0;
    }

  5. #5
    Membre Expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Par défaut
    Citation Envoyé par escafr Voir le message
    --
    En resumé, je veux locker une ligne precise pour un temps indeterminé pour un utilisateur qui peut faire ce qu'il veut dessus (UPDATE, DELETE).
    Mais je veux que cette ligne soit accessible en lecture par les autres utilisateurs (SELECT).
    Les verrous oracle sont ils adaptés à cela?
    Non, les verrous posés sur des lignes de tables par SELECT FOR UPDATE, UPDATE, DELETE et INSERT ne sont gardés que le temps de la transaction qui les a posés càd jusqu'au COMMIT ou ROLLBACK. Un verrou sur une ligne ne peut pas être posé pour un temps indéterminé ... sauf si la transaction dure un temps indéterminé, ce qui n'est pas vraiment recommandé.

    Votre problème ressemble à celui du "lost update": voir à ce sujet l'extrait en anglais de Expert Oracle de Tom Kyte.

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

Discussions similaires

  1. Verrou sur ligne d'une table
    Par egelitros dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 24/05/2018, 09h25
  2. Problème de verrou sur Oracle 10 g
    Par GH dans le forum Oracle
    Réponses: 14
    Dernier message: 03/09/2009, 11h01
  3. [T-SQL]verrou sur une ligne avant un select
    Par dinobogan dans le forum Sybase
    Réponses: 3
    Dernier message: 28/06/2007, 14h36
  4. verrou sur ligne
    Par petit arbre dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 14/11/2006, 21h54
  5. [ORACLE 10g] Droits en ligne sur une table
    Par Cerberes dans le forum Oracle
    Réponses: 4
    Dernier message: 04/02/2005, 10h39

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