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

Développement SQL Server Discussion :

Concurrence d'appel d'une instruction SQL


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 53
    Par défaut Concurrence d'appel d'une instruction SQL
    Bonjour à tous,

    Je suis dans une entreprise du web, j'écris des procédures stockées t-sql qui servent de web services et qui sont donc appelées par un grand nombre de clients simultanément.
    Je rencontre un problème de concurrence d'appel à un de mes web services: on doit l'appeler plusieurs fois avec la même variable @nouveau_id, mais a des fins statistiques je ne veux l'enregistrer qu'une fois en table

    Il contient la simple instruction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    insert into ma_table(id, date)  /* avec id primary key sur ma_table */
      select distinct @nouveau_id, getdate()
      from ma_table
      where @nouveau_id is not null
      and not exists (
        select id
        from ma_table
        where id = @nouveau_id)
    Je pensais de cette manière être tranquille et être sûr que je n'aurais jamais d'insertion double de clé primaire, pourtant j'ai régulièrement des erreurs à l'insertion pour violation de clé primaire. La seule explication que j'ai trouvée est des appels simultanés de mon web service.
    J'ai essayé de jouer avec les niveaux d'isolation (j'ai à peu près tout essayé), mais rien n'a changé, j'ai toujours des tentatives d'insertion double.

    Je voulais savoir s'il y avait un moyen de poser manuellement un verrou sur la table, pour entourer mon instruction SQL et être sûr de ne pas avoir de concurrence du tout.
    Sinon, y a t'il un autre moyen d'éviter ce problème?

    En vous remerciant, Thomas

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 002
    Billets dans le blog
    6
    Par défaut
    Le plus simple et le plus efficace est de mettre une contrainte d'unicité et de rejeter l'insertion en cas de viol de la contrainte.

    Tout autre technique ne pourra que nuire, voir donner des temps de réponse de plus en plus catastrophiques.


    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre émérite
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 623
    Par défaut
    Sinon il y aurait la possibilité de mettre la colonne en auto-incrément ou sequence.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 53
    Par défaut
    Bonjour SQL Pro,
    Ma colonne "id" est clé primaire de la table, elle fait donc office de contrainte d'unicité, non? D'ailleurs j'ai bien une erreur "violation primary key"

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 53
    Par défaut
    Bonjour darkelend,
    Je ne peux pas faire de l'autoincrément, ce n'est pas l'idée du tout:
    Le besoin est de connaître le nombre de user unique par jour sur toutes nos plateformes confondues (web, mobile, pad, sur tous les os). Un user, de part la multitude de nos plateformes peut interroger notre service par n'importe quel web service, il n'y a pas de point d'entrée obligatoire. Pour l'enregistrer, une fois par jour, nous avons donc intégrer le bout de code ci-dessous au début de chacun de nos webs services:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    /* si l'id du user n'est pas enregistré à ce jour, on l'enregistre dans la table de tracking */
    insert into TableTracking (id_user, dateAction)				
      select distinct @id_user, CONVERT(date, getdate())
      from TableTracking
      where not exists (
        select id_user
        from TableTracking
        where id_user = @id_user
        and dateAction = CONVERT(date,getdate()))
    malgré la clause "not exists" à même l'instruction d'insertion, nous avons des tentatives d'insertion sur des clés doubles (j'ai une erreur "violation primary key"). Nous avons interprété cela par des appels concurrents effectués par un même user, mais ça se trouve le diagnostic n'est pas bon

  6. #6
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Billets dans le blog
    3
    Par défaut
    Le problème c'est que si par exemple l'utilisateur 1 fait une action le 1/1/2013 tu auras cette ligne :
    id_user = 1
    dateAction = 1/1/2013
    Si le lendemain il refait une action :
    id_user = 1
    dateAction = 2/1/2013
    Ca plante, car l'id_user 1 est déjà utilisé.

    Dans ce cas il faudrait :
    - soit mettre une clef primaire composée des deux colonnes id_user et dateAction (la valeur de dateAction permettra de différencier les lignes),
    - soit rajouter une colonne ID auto-incrémentée (ou séquence si Oracle) qui servira de clef primaire et qui permettra de distinguer clairement et arbitrairement les enregistrements.
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

Discussions similaires

  1. Remplir une table avec le résultat d'une instruction SQL
    Par jbeu dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 02/09/2007, 23h49
  2. caractère critique dans une instruction sql
    Par Damien10 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 05/01/2007, 16h54
  3. récupérer une instruction sql
    Par oracliste dans le forum Oracle
    Réponses: 2
    Dernier message: 09/11/2006, 11h41
  4. Remplacer l'instruction GO par une instruction SQL
    Par Sytchev3 dans le forum MS SQL Server
    Réponses: 14
    Dernier message: 06/04/2006, 09h28
  5. Passer de la zone d'édition vers une instruction sql
    Par tripper.dim dans le forum C++Builder
    Réponses: 2
    Dernier message: 27/11/2002, 14h44

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