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

ASP.NET Discussion :

Probleme conception , ergonomie


Sujet :

ASP.NET

  1. #1
    LEK
    LEK est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    715
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 715
    Par défaut Probleme conception , ergonomie
    Bonsoir,
    j'ai une question concernant un petit problème d'ergonomie : je développe une webform présentant de multiple informations sur une entité "contact" (provient en base d'une table contact) : sur ma page j'ai un onglet "adresse(s)" (table adress_contact), un autre onglet "suivi" (table historique_contact),etc...
    Lorsque l'utilisateur clique sur le bouton sauvegarder je dois d'abord enregistrer mon contact en base puis avec son identifiant renseigner les différentes infos provenant des onglets en base.... Là j'ai déjà un problème car cet identifiant m'est donné par une séquence oracle où je ne dois pas avoir de trou or, si un problème se produit en cours de route je dois annuler ma transaction...
    Je voulais savoir comment en général vous traitiez ce genre de problème.

    Merci de vos conseils,
    Lek.

  2. #2
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    une séquence oracle où je ne dois pas avoir de trou
    Mauvais plan, c'est à éviter absolument car :
    - l'annulation d'une transaction ORACLE n'annule pas les éventuelles incrémentations du numéro de séquence,
    - et, même si c'était le cas, tu pourrais avoir un problème si plusieurs nouveaux contacts sont traités en même temps.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Une séquence Oracle n'est pas la bonne solution, pour la raison expliquée par Graffito.

    Il vaudrait mieux gérer manuellement les numéros de séquence dans une table genre ça :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TABLE CHRONO
    (
        CHRONO_ID VARCHAR2(30) NOT NULL PRIMARY KEY,
        CHRONO_VALUE NUMBER NOT NULL
    );

    Quand tu veux récupérer la prochaine valeur du chrono "CUSTOMER_ID" par exemple, tu fais ça :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT CHRONO_VALUE + 1
    FROM CHRONO
    WHERE CHRONO_ID = 'CUSTOMER_ID'
    FOR UPDATE

    La clause "FOR UPDATE" verrouille la ligne jusqu'à la fin de la transaction, donc tu peux tranquillement mettre à jour ta base sans t'inquiéter qu'un autre thread utilise le même ID (si un autre thread exécute la même requête avec "FOR UPDATE", son exécution sera bloquée jusqu'à ce que la ligne soit libérée)
    En cas de problème => ROLLBACK, et ton chrono n'est pas modifié (contrairement à une séquence).

    Par contre, n'oublie pas d'incrémenter le chrono avant de valider la transaction :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE CHRONO
    SET CHRONO_VALUE = CHRONO_VALUE + 1
    WHERE CHRONO_ID = 'CUSTOMER_ID'

  4. #4
    LEK
    LEK est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    715
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 715
    Par défaut
    Merci pour votre aide, cela répond à mon problème pour la partie liaison avec la bdd... Mais côté asp.net, je voulais savoir comment vous géreriez ce type de problématique : dois-je par exemple implémenter une méthode save dans chacun de mes user control (par onglet) afin de leur fournir la séquence à utiliser pour qu'il puisse en contrôle responsable mettre à jour la base... Ou bien depuis ma page asp, je dois contrôler l'ensemble des opérations en effectuant de manière centralisé toute les opérations de sauvegarde : à ce moment les user control se contentent de rester de gentil conteneur opaque qui m'expose deux ou trois propriété utiles...

    Merci d'avance pour vos réponses,
    Lek.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Clairement, il vaudrait mieux gérer ça de manière centralisée dans une couche d'accès aux données (DAL), pour éviter de dupliquer inutilement du code.

    La méthode que j'utiliserais pour gérer ces chronos reposerait sur un objet IDisposable, donc utilisable dans un bloc using pour être sûr de ne pas oublier d'incrémenter le chrono après usage :

    (désolé c'est du C#, trop la flemme d'écrire du VB... mais ça se traduit facilement )

    Code C# : 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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    public class DbChrono : IDisposable
    {
        private string _chronoID;
        private DbConnection _connection;
        private DbTransaction _transaction;
     
        public long Value { get; private set; }
     
        public DbChrono(string chronoID, DbConnection connection, DbTransaction transaction)
        {
            _chronoID = chronoID;
            _connection = connection;
            _transaction = transaction;
     
            GetChronoValue();
        }
     
        private void GetChronoValue()
        {
            using (DbCommand command = _connection.CreateCommand())
            {
                command.CommandText =  @"
                    SELECT CHRONO_VALUE + 1
                    FROM CHRONO
                    WHERE CHRONO_ID = :CHRONO_ID
                    FOR UPDATE";
     
                DbParameter parameter = command.CreateParameter;
                parameter.ParameterName = "CHRONO_ID";
                parameter.DbType = DbType.String;
                parameter.Value = _chronoID;
     
                command.Transaction = _transaction;
     
                this.Value = Convert.ToInt64(command.ExecuteScalar());
            }
        }
     
        public void Dispose()
        {
            UpdateChronoValue();
        }
     
        private void UpdateChronoValue()
        {
            using (DbCommand command = _connection.CreateCommand())
            {
                command.CommandText =  @"
                    UPDATE CHRONO
                    SET CHRONO_VALUE = CHRONO_VALUE + 1
                    WHERE CHRONO_ID = :CHRONO_ID";
     
                DbParameter parameter = command.CreateParameter;
                parameter.ParameterName = "CHRONO_ID";
                parameter.DbType = DbType.String;
                parameter.Value = _chronoID;
     
                command.Transaction = _transaction;
     
                command.ExecuteNonQuery();
            }
        }
    }

    Et pour l'utiliser (en supposant que tu aies déjà une connexion ouverte et une transaction en cours) :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    using (DbChrono chrono = new DbChrono("CUSTOMER_ID", connection, transaction))
    {
     
         long customerID = chrono.Value;
         // Etc...
     
     
    } // Le chrono est automatiquement mis à jour ici

    J'ai écrit ça à la volée, donc c'est évidemment pas testé, et je décline toute responsabilité en cas de dysfonctionnement

  6. #6
    LEK
    LEK est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    715
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 715
    Par défaut
    OK, merci pour le code :
    (désolé c'est du C#, trop la flemme d'écrire du VB... mais ça se traduit facilement )
    Pas de problème, j'écris aussi en C#, je n'avais tout simplement pas fais gaffe que j'étais dans le forum VB.
    Merci encore pour votre implication ;-)

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

Discussions similaires

  1. Probleme conception graphique / ergonomique
    Par SebastianPx dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 20/04/2009, 09h37
  2. [POO] probleme conception objet
    Par vraipolite dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 16/01/2009, 09h00
  3. Probleme conception de requete
    Par Alex35 dans le forum Langage SQL
    Réponses: 6
    Dernier message: 25/06/2008, 10h27
  4. [pseudo debutant] Probleme conception et access
    Par zax-tfh dans le forum Modélisation
    Réponses: 1
    Dernier message: 01/12/2005, 16h16

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