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

VB.NET Discussion :

Multithreading et INSERT


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    125
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2008
    Messages : 125
    Par défaut Multithreading et INSERT
    Bonjour à tous,

    J'espère poster dans la bonne section. Voici mon problème. Je développe actuellement un programme de récupération des emails avec insertion dans une base de données PostgreSQL. J'utilise le multithreading pour pouvoir améliorer les performances, et extraire les message de plusieurs utilisateurs en même temps.
    Mon soucis et qu'il m'arrive d'avoir une incohérence dans ma base de données du fait du multithreading. Par exemple, j'ai dans ma table 60 messages, il arrive parfois qu'a la même seconde, mes 2 threads font une requete pour compter le nombre de messages dans la table avant insertion, et du coup, insère le même n°ID dans ma table

    J'espère que je suis assez claire dans ma description, car c'est vraiment un phénomène bizarre que je n'arrive pas à comprendre.

    Avez vous une théorie pour contrer ce problème ?

    Merci à tous.

  2. #2
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Ne pourrais-tu pas simplement utiliser une colonne auto-incrémentée pour l'ID ?

    Sinon, puisque ta DB ne semble être pilotée que par une unique copie de ton application, plutôt que d'utiliser une requête du nombre de lignes pour déterminer le nouvel ID, tu pourrais simplement maintenir un champ que tu mettrais à jour via la classe Interlocked ou des verrous.

  3. #3
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    125
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2008
    Messages : 125
    Par défaut
    Merci pour ta réponse.

    Si je ne confond pas, les verrous sont mis en place par des transactions c'est bien ça ? Si c'est le cas, je dois voir si c'est faisable avec mon ODBC vers Postgresql... pourrais tu m'en dire un peu plus sur ces verrous ou une classe Interlocked ?

    Merci beaucoup.

  4. #4
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Bonjour.

    Non, pas ces verrous-là. Je pensais aux primitives de synchronisation dotnet (les instructions "lock", les classes Monitor, Interlocked). Aucun rapport les mécanismes de concurrence des DB. Encore une fois, ceci ne serait valable que si ta DB n'est consommée que par une seule copie d'une seule application mais, si c'est le cas, ce serait le plus efficace.

    Si ce n'est pas le cas et qu'un champ autoincrémenté n'est pas possible, le plus simple est de retenter la transaction jusqu'à ce que ça passe (concurrence optimiste, idéal quand tu as peu d'accès simultanés).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while(true)
    {
        int id = NbLignes() + 1;
        if (EssayerInsertion(id) == "success") break;
    }
    Tu peux aussi tenter une requête imbriquée, avec "VALUES((SELECT COUNT(*) FROM matable), 'dupont', 'jean')" mais je ne crois pas que ça fonctionne.

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    le mieux reste le champ auto incrément sinon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    insert into table (ch1, ch2) values ((select max(ch1) +1 from table), vCh2)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    125
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mai 2008
    Messages : 125
    Par défaut
    Merci pour ces informations.

    Malheureusement, le champ autoincrémenté n'est pas possible et la DB n'est pas consommée que par une seule copie d'une seule application.

    En général, l'insertion passe toujours, mais mon problème se situe au niveau du multithreads. C'est a dire que 2 threads insère une ligne en même temps, et comme je fais un SELECT COUNT(*) juste avant pour récupérer le nombre d'éléments dans ma table, les 2 threads insérent le même id en même temps...

    Je vais essayer de gérer ça par des transactions ou avec BULK, peut être que c'est une possibilité.

Discussions similaires

  1. STL list insertion Multithreading
    Par pavel dans le forum C++
    Réponses: 2
    Dernier message: 17/03/2010, 14h00
  2. probleme d'insertion d'un Float
    Par neness dans le forum Débuter
    Réponses: 3
    Dernier message: 07/01/2003, 12h32
  3. [Postgresql] pb lors d'insertion de données
    Par bob20000 dans le forum Requêtes
    Réponses: 8
    Dernier message: 04/11/2002, 15h33
  4. Multithreading sous HP Ux 11
    Par pykoon dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 18/10/2002, 23h36
  5. Réponses: 4
    Dernier message: 28/09/2002, 00h00

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