|
| [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")
SQLChangeConnexion(VaINT_ID_CONNEXION_1)
SQLTransaction(sqlDébut)
SI(MaPROCEDURE_1() = Vrai) ALORS
SQLChangeConnexion(VaINT_ID_CONNEXION_2)
SI(MaPROCEDURE_2() = Vrai) ALORS
SQLChangeConnexion(VaINT_ID_CONNEXION_1)
SQLTransaction(sqlFin) RENVOYER Vrai SINON
SQLChangeConnexion(VaINT_ID_CONNEXION_1)
SQLTransaction(sqlAnnule) RENVOYER Faux FIN SINON
SQLTransaction(sqlAnnule) RENVOYER Faux FIN
Procedure MaPROCEDURE_1()
SQLTransaction(sqlDébut)
SI(SQLExec("Texte de ma requête",Ma_Requete_1) = Vrai) ALORS SI(Mon_Traitement() = Vrai)ALORS
SQLTransaction(sqlFin) RENVOYER Vrai SINON
SQLTransaction(sqlAnnule) RENVOYER Faux FIN SINON
SQLTransaction(sqlAnnule) RENVOYER Faux FIN FIN
Procedure MaPROCEDURE_2()
SQLTransaction(sqlDébut)
SI(SQLExec("Texte de ma requête",Ma_Requete_2) = Vrai) ALORS SI(Mon_Traitement() = Vrai)ALORS
SQLTransaction(sqlFin) RENVOYER Vrai SINON
SQLTransaction(sqlAnnule) RENVOYER Faux FIN SINON
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 ) |
| |
| |
| | | |
|
| | |
| |
| 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 |
| |
| |
| | | |
|
| | | | |
| | |
|