PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 2025 → [WD17] Transactions SQL avec plusieurs connexions
[WD17] Transactions SQL avec plusieurs connexions
Iniciado por m.neel, 13,sep. 2012 19:42 - 5 respuestas
Publicado el 13,septiembre 2012 - 19:42
Bonjour,

je rencontre actuellement un soucis avec une de mes applications.

Celle-ci doit désormais gérer des écritures dans deux bases de données SQL Server en parallèle.
Certains traitements sont effectués dans des transactions pour faciliter le roll back en cas d'erreurs.
Nous utilisons pour manipuler ces bases les fonctions SQL de Windev.

J'ai cependant un problème lorsque je change de connexion, il semblerait que l'imbrication de transactions sur la même connexion ne soit pas bien prise en compte.

En effet, j'ouvre une transaction "globale" sur ma 1ère connexion, j'en ouvre ensuite une autre sur cette même connexion et j'effectue des traitements.
Si ceux-ci se déroulent bien, je ferme ma seconde transaction (il m'en reste donc une ouverte de plus haut niveau)

Je change ensuite de connexion et ouvre une transaction sur cette deuxième connexion pour effectuer des traitements sur la seconde base de données.
Si ces traitements échouent, j'annule ma transaction et je rebascule sur ma première connexion, sur laquelle j'annule ma transaction "globale".
Là, je me rends malheureusement compte que ma transaction "globale" a été validée et non annulée, les modifications dans la BDD de ma 1ère connexion ont été prises en compte.



Pouvez-vous me dire si le changement de connexion valide toute transaction ouverte sur la précédente connexion ?



Vous trouverez ci-après un protocole de reproduction du code (simplifié) expliquant les traitements que j'effectue dans mon application.


Cordialement.



P.S. : Dsl pour l'indentation du code, mais la balise code ne me laisse pas présenter le code comme je veux.


Protocole de reproduction :

VaINT_ID_CONNEXION_1 est un entier = SQLConnecte(Mon_Serveur_1,Mon_User,Mon_Password,Ma_Base_De_Donnees_1,"SQL SERVER")

VaINT_ID_CONNEXION_2 est un entier = SQLConnecte(Mon_Serveur_2,Mon_User,Mon_Password,Ma_Base_De_Donnees_2,"SQL SERVER")

// Je bascule sur ma 1ère connexion
SQLChangeConnexion(VaINT_ID_CONNEXION_1)

// J'ouvre une transaction sur la connexion VaINT_ID_CONNEXION_1
SQLTransaction(sqlDébut)

// Je teste la valeur de retour de ma 1ère procédure
SI(MaPROCEDURE_1() = Vrai) ALORS
// Si Ma_Procedure_1 renvoie Vrai, je rends active ma 2nde connexion
SQLChangeConnexion(VaINT_ID_CONNEXION_2)
// Je teste la valeur de retour de ma 2nde procédure
SI(MaPROCEDURE_2() = Vrai) ALORS
// Si Ma_Procedure_2 renvoie Vrai, je bascule sur ma 1ère connexion
SQLChangeConnexion(VaINT_ID_CONNEXION_1)
// Puis je termine ma transaction sur la connexion VaINT_ID_CONNEXION_1 pour valider mes modifications sur Ma_Base_De_Donnees_1
SQLTransaction(sqlFin)
RENVOYER Vrai
SINON
// Si Ma_Procedure_2 renvoie Faux, je bascule sur ma 1ère connexion
SQLChangeConnexion(VaINT_ID_CONNEXION_1)
// Puis j'annule ma transaction sur la connexion VaINT_ID_CONNEXION_1 pour annuler mes modifications sur Ma_Base_De_Donnees_1
SQLTransaction(sqlAnnule)
RENVOYER Faux
FIN
SINON
// Si Ma_Procedure_1 renvoie Faux, j'annule ma transaction sur la connexion VaINT_ID_CONNEXION_1 pour annuler mes modifications sur Ma_Base_De_Donnees_1
SQLTransaction(sqlAnnule)
RENVOYER Faux
FIN

Procedure MaPROCEDURE_1()
// J'ouvre une transaction sur la connexion VaINT_ID_CONNEXION_1
SQLTransaction(sqlDébut)
// Je teste l'exécution de Ma_Requete_1
SI(SQLExec("Texte de ma requête",Ma_Requete_1) = Vrai) ALORS
SI(Mon_Traitement() = Vrai)ALORS
// Je ferme ma transaction sur la connexion VaINT_ID_CONNEXION_1
SQLTransaction(sqlFin)
RENVOYER Vrai
SINON
// J'annule ma transaction sur la connexion VaINT_ID_CONNEXION_1
SQLTransaction(sqlAnnule)
RENVOYER Faux
FIN
SINON
// J'annule ma transaction sur la connexion VaINT_ID_CONNEXION_1
SQLTransaction(sqlAnnule)
RENVOYER Faux
FIN
FIN

Procedure MaPROCEDURE_2()
// J'ouvre une transaction sur la connexion VaINT_ID_CONNEXION_2
SQLTransaction(sqlDébut)
// Je teste l'exécution de Ma_Requete_2
SI(SQLExec("Texte de ma requête",Ma_Requete_2) = Vrai) ALORS
SI(Mon_Traitement() = Vrai)ALORS
// Je ferme ma transaction sur la connexion VaINT_ID_CONNEXION_2
SQLTransaction(sqlFin)
RENVOYER Vrai
SINON
// J'annule ma transaction sur la connexion VaINT_ID_CONNEXION_2
SQLTransaction(sqlAnnule)
RENVOYER Faux
FIN
SINON
// J'annule ma transaction sur la connexion VaINT_ID_CONNEXION_2
SQLTransaction(sqlAnnule)
RENVOYER Faux
FIN
FIN
Publicado el 13,septiembre 2012 - 22:57
Bonjour,

Une transaction n'affecte pas une autre connexion que celle qui l'a ouverte. Cela fonctionne très bien avec SQL Server, mais je n'ai jamais utilisé SQLTransaction().

J'ai troujours fait cela avec :
SQLExec("begin transaction xxx")
SQLExec("rollback transaction xxx")
SQLExec("commit transaction xxx")

Daniel
Publicado el 14,septiembre 2012 - 13:01
Daniel a écrit dans le message de news <113998d2c7f23253ea9c46a79d2a7e97@news.pcsoft> :
Bonjour,

Une transaction n'affecte pas une autre connexion que celle qui l'a ouverte. Cela fonctionne très bien avec SQL Server, mais je n'ai jamais utilisé SQLTransaction().

J'ai troujours fait cela avec :
SQLExec("begin transaction xxx")
SQLExec("rollback transaction xxx")
SQLExec("commit transaction xxx")

Daniel




Merci Daniel pour cette réponse.

Je vais suivre cette piste pour gérer mes transactions en lançant des ordres SQL à mon serveur, plutôt que d'utiliser la fonction SQLTransaction().

Je posterai l'avancement de la résolution de mon problème.
Publicado el 14,septiembre 2012 - 17:55
Je rencontre à nouveau un problème. J'ai tenté de gérer les transactions en utilisant des SQLExec("begin transaction " + Nom_de_ma_transaction), j'ai obtenu l'erreur suivante :

-------------------------------------------
Erreur de l'accès natif SQLSERVER.
Numéro d'erreur = 4504

SQL Server a renvoyé l'erreur 80040e14
Une transaction qui a été démarrée dans un traitement MARS est toujours active à la fin du traitement. La transaction est annulée.
SQL State: 42000
SQL Error Number:3997
La base a renvoyé une erreur lors de l'exécution de la requête suivante :
begin transaction ClBDD_ENTETE_ODF
-------------------------------------------


Avez-vous déjà rencontré une erreur de ce type ?

Merci d'avance.
Publicado el 26,abril 2020 - 09:21
Bonjour,

Je suis en train de migrer l'une de mes applications sur SQL Server et je rencontre le même problème : "Une transaction qui a été démarrée dans un traitement MARS est toujours active à la fin du traitement. La transaction est annulée."

Aviez-vous trouver une solution à l'époque ? Si oui... je suis preneur ...

D'avance merci !

(En plus il me parle de mars et on est en avril :D)
Publicado el 26,abril 2020 - 18:29
Hello,
MARS = Multiple Active Result Sets
Ce serait intéressant de savoir ce qui a été exécuté comme requête SQL pour savoir pourquoi il y a plusieurs jeux de résultat
Daniel