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

  1. #1
    Futur Membre du Club
    Inscrit en
    Avril 2010
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 13
    Points : 8
    Points
    8
    Par défaut DB Sql accès via ODBC multithread. [ERROR [HY000] [Microsoft][ODBC SQL Server Driver]La connexion est occupée]
    Bonjour,

    J'essaie de faire une application pour tester la mise en charge d'une base de donnée.

    Pour ce faire, j'aimerais exécuté des requêtes en parallèle sur une base de donnée.
    La connexion doit être partagée entre les différents threads (pour reproduire le mode de fonctionnement de l'application de base).

    Je crée donc mon pool de thread en leur passant l'objet d'interaction avec la base de donnée.
    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
    try
    {
        myDbAcces = new DataBaseAccesOdbcViaDSN(...);
    }
    catch (Exception exc)
    {
        //ToDo Retry
        MessageBox.Show("Error while connecting to database : " + exc.Message, "Error DataBase", MessageBoxButtons.OK, MessageBoxIcon.Error);
     
        Environment.Exit(-1);
    }
             myThreads = new LinkedList<Thread>();
     
    for (int i = 0; i < myNbrOfThread; i++)
    {
        ThreadSQL ThSQL = new ThreadSQL(myDbAcces, myCmd, myInterval, "Thread"+i);
        myThreads.AddLast(new Thread(ThSQL.Run));
        if (!ThSQL.CheckCmd())
            MessageBox.Show("Error while formating the command, please check your command file.");
    }
     
    foreach (Thread tThr in myThreads)
    {
        tThr.Start();
    }
    La méthode Run de la classe ThreadSQL ne fait que modifier la commande a exécuter et la lancer :
    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
                try
                {
                    isAlive = true;
                    while (isAlive)
                    {                    
                        myDbAccess.ExecuteCommand(myCmds.Replace("%EditName%", "N'" + myName +" "+ DateTime.Now + "'"));
     
                        Thread.Sleep(mySleep);
                    }
                }
                catch (ThreadAbortException)
                {
                    Debug.WriteLine(myName + " aborted.");
                    isAlive = false;
                }
    Et la méthode ExecuteCommand est comme ceci:
    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
            public LinkedList<LinkedList<Object>> ExecuteCommand(string pCmd)
            {
                LinkedList<LinkedList<Object>> Tab_Ret = new LinkedList<LinkedList<Object>>();
     
                int i = 0;
     
                Debug.WriteLine("DataBaseAccesOdbcViaDSN - ExecuteCommand ");
     
                OdbcCommand myOdbcCmd = new OdbcCommand(pCmd, myOdbcCo);
     
                OdbcDataReader oRdr = myOdbcCmd.ExecuteReader();
     
                if (oRdr != null)
                {
                    while (oRdr.Read())
                    {
                        LinkedList<Object> tLlObj = new LinkedList<object>();
     
                        for (i = 0; i < oRdr.FieldCount; i++)
                        {
                            tLlObj.AddLast(oRdr.GetValue(i));                        
                        }                    
                        Tab_Ret.AddLast(tLlObj);
                        Debug.WriteLine("DataBaseAccesOdbcViaDSN - ExecuteCommand Result: " + Tab_Ret.ToString());
                    }                
                    oRdr.Close();
     
                }
                myOdbcCo.Dispose();
     
                return Tab_Ret;
            }
    Le problème vient de:
    OdbcDataReader oRdr = myOdbcCmd.ExecuteReader();
    Et me renvoi donc l'exception :
    [System.Data.Odbc.OdbcException]
    ERROR [HY000] [Microsoft][ODBC SQL Server Driver]La connexion est occupée avec les résultats d'un autre hstmt
    Donc la première requête s'exécute mais il bloque sur la deuxième en disant que la connexion est occupée.
    Il faudrait donc relâcher la connexion mais je ne sais pas trop comment.

    Je pourrais utiliser un sémaphore ou un mutex, mais les requêtes ne s'exécuteraient plus en parallèle...

    Des idées et suggestions ?

    Merci pour votre aide !

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    le seul moyen d'exécuter plusieurs requêtes en même temps est d'avoir une connexion pour chaque, pas de la partager
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Comme mentionné par Pol63, tu ne peux pas exécuter plusieurs commande en même temps sur la même connection.

    Néanmoins en synchronisant tes threads proprements (c'est à dire avec des objets de synchro et pas avec des trucs pourris comme cet horrible "Sleep" et le "isAlive" que je vois dans ton code pour lequel je n'ose même songer à la façon dont tu l'utilises ), tu peux paralléliser relativement : attendre qu'une commande se termine sur un thread avant de commencer à exécuter la commande sur un autre, et à condition que la commande ne soit pas une obtention de DataReader, car pour les DataReader, de toute manière, thread ou pas thread, tu ne peux en avoir qu'un seul d'actif à un moment donné sur la connexion.

    Par ailleurs, je ne vois pas bien l'interêt ici de n'utiliser qu'une seule connection.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  4. #4
    Futur Membre du Club
    Inscrit en
    Avril 2010
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    IsAlive c'est juste une variable pour ne pas que le thread soit sur une condition tout le temps vrai.
    Et le Sleep c'est le temps d'attente entre les commandes et non pas un système de synchronisation douteuse.

    Merci pour votre aide, je vais essayé d'une part de faire un système de synchro pour ce mode de fonctionnement.
    Et faire une connexion pour chaque thread.
    (J'avais mal comprit les exigences du projet en fait je pense.)

Discussions similaires

  1. Réponses: 1
    Dernier message: 30/11/2010, 14h11
  2. Problème d'accès via ODBC
    Par Nicolas_SW dans le forum Administration
    Réponses: 4
    Dernier message: 08/03/2010, 10h06
  3. Acces via ODBC en ecriture
    Par gueguenk dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 10/03/2009, 08h46
  4. Accès SQL serveur via ADO
    Par Fbartolo dans le forum C++Builder
    Réponses: 1
    Dernier message: 25/05/2007, 10h18
  5. Différence accès via PL/SQL et .NET
    Par Stef69_ dans le forum PL/SQL
    Réponses: 2
    Dernier message: 24/10/2006, 10h08

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