PC SOFT

PROFESSIONAL NEWSGROUPS
WINDEVWEBDEV and WINDEV Mobile

Home → WINDEV (earlier versions) → [WD22] Problème de connexion SQL avec les threads
[WD22] Problème de connexion SQL avec les threads
Started by Adrien D., Jun., 01 2018 5:00 PM - 4 replies
Registered member
3 messages
Posted on June, 01 2018 - 5:00 PM
Bonjour,

Je suis sur une application Windows en WinDev22.

J’ai un souci avec l’utilisation d’une connexion SQL (ODBC SQL Serveur) dans des threads :
Lorsque j’utilise la connexion SQL depuis le processus principal (hors thread), le résultat de SQL.NbLig est parfois incorrect.

Voici comment j’ai reproduit ce bug :
J’ai un thread qui lance une requête en boucle :
Procedure DEBUG_select()

ResSQL est un booléen
cpt_erreur est un entier = 0
nom_req est une chaîne

SQLConnecte("sourceBDD", "userBDD", "mdpBDD")

POUR i = 1 _A_ 1000
nom_req = "REQ"+DonneIdentifiant()

ResSQL = SQLExec("SELECT MA_CLE FROM MA_TABLE WHERE MA_CLE = 1", nom_req)
SI ResSQL=Vrai ALORS
SQLPremier(nom_req) // Affiche la première ligne

SI SQL.NbLig <> 0 ALORS
//Trace("["+ThreadCourant()+"] SQL.NbLig = "+SQL.NbLig)
cpt_erreur++
FIN
SINON
Trace("["+ThreadCourant()+"] Erreur SQLExec ")
FIN
SQLFerme(nom_req)
FIN

Trace("["+ThreadCourant()+"] cpt_erreur = "+cpt_erreur+" / "+1000)

SQLDéconnecte()

La table est vide, NbLig doit donc renvoyer 0.

Dans le code du projet, je lance 3 fois ce thread :
ThreadMode(threadSectionCritique)
// Fonctionne
ThreadExecute("THREAD TEST AD 1",threadCopieComplèteContexteHFSQL,DEBUG_select)
ThreadExecute("THREAD TEST AD 2",threadCopieComplèteContexteHFSQL,DEBUG_select)
ThreadExecute("THREAD TEST AD 3",threadCopieComplèteContexteHFSQL,DEBUG_select)

Aucun problème jusqu’ici, mes requêtes me renvoient toutes NbLig = 0

Mais, si je fais un SQLConnecte dans le thread principal :
ThreadMode(threadSectionCritique)
// Ne fonctionne pas
SQLConnecte("sourceBDD", "userBDD", "mdpBDD")
ThreadExecute("THREAD TEST AD 1",threadCopieComplèteContexteHFSQL,DEBUG_select)
ThreadExecute("THREAD TEST AD 2",threadCopieComplèteContexteHFSQL,DEBUG_select)
ThreadExecute("THREAD TEST AD 3",threadCopieComplèteContexteHFSQL,DEBUG_select)

Là ça ne fonctionne plus : mes requêtes ne revoient pas toutes NbLig = 0. Parfois elles renvoient 1 et parfois elles renvoient 2 !
Après avoir essayé plusieurs choses, ce que je déduis c’est que dès que j’essaie de faire une connexion SQL dans le processus principal, mes résultats sont faussés.
Cependant, je ne peux pas me permettre de faire mes requetes uniquement dans des threads.


Ce bug de SQL.NbLig est-il connu ?
Comment puis-je faire pour obtenir un résultat correct ?

Merci d'avance pour vos retours !


Voici mes tentatives de résolution infructueuses :
- Appeler SQLDéconnecte avant le lancement des threads
- Modifier l’option de lancement des threads
- Appeler un sous thread qui effectue le même traitement dans mes threads
- D’autres programmes sont susceptibles de se connecter à la base mais j’ai créé une table vide pour mes tests et aucun autre programme n’y accède

--
Adrien D.
Message modified, June, 01 2018 - 5:02 PM
Posted on June, 02 2018 - 11:22 PM
Utilisez un Select Count(*)
Registered member
3 messages
Posted on June, 04 2018 - 11:20 AM
michell a écrit :
> Utilisez un Select Count(*)


Bonjour,

Merci pour votre retour,

Il faudrait alors doubler absolument toutes mes requêtes, ce ne serait pas du tout optimisé !

De plus, le traitement étant fait par des threads, entre le SELECT COUNT(*) et le SELECT à parcourir, il est possible que des lignes soient insérées et le résultat serait faux !

Cela ne conviens pas...

--
Adrien D.
Posted on June, 04 2018 - 4:53 PM
Cela ne double la requête que si le nombre renvoyé est supérieur à 0
Mais je ne connais pas assez votre contexte.

Si vous utilisez SQLAvance pour lire vos informations est-ce que vous obtenez un résultat différent ?
Je suis aussi en SQL Serveur, j'ai construit une classe basé là dessus et ça marche bien
Registered member
3 messages
Posted on June, 25 2018 - 3:27 PM
Michel a écrit :
Cela ne double la requête que si le nombre renvoyé est supérieur à 0
Mais je ne connais pas assez votre contexte.


Effectivement ca ne double la requete que s'il y a des résultats, cependant l'exemple ci-dessus est un cas de test d'un problème rencontré dans mes programmes de prod qui eux trouvent des résultats.


Michel a écrit :
Si vous utilisez SQLAvance pour lire vos informations est-ce que vous obtenez un résultat différent ?
Je suis aussi en SQL Serveur, j'ai construit une classe basé là dessus et ça marche bien


D'après la documentation de windev, SQLAvance ne récupère que les données de la ligne en cours et pas de la requete, c'est donc incompatible avec SQL.NbLig
Si j'essaie, le nombre de lignes obtenu est toujours 0, même s'il y a des résultats


J'ai également construit une classe pour manipuler ma base de données, elle fonctionnait bien jusqu'à ce qu'on s’aperçoive de ce bug dans certains cas précis de threads concurrents.

--
Adrien D.