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.
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
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(); }
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 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; }
Le problème vient de:
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; }
OdbcDataReader oRdr = myOdbcCmd.ExecuteReader();
Et me renvoi donc l'exception :
Donc la première requête s'exécute mais il bloque sur la deuxième en disant que la connexion est occupée.[System.Data.Odbc.OdbcException]
ERROR [HY000] [Microsoft][ODBC SQL Server Driver]La connexion est occupée avec les résultats d'un autre hstmt
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 !
Partager