Bonjour,
je rencontre actuellement un problème de transactions sur plusieurs de mes applications.
Mes applications sont des applications client/Serveur connectées via des sockets (IP + Port).
Chaque client qui se connecte aux serveurs est un nouveau thread.
Au niveau Oracle et système je travaille avec Oracle 11.2 en 64 bits et client 32 bits avec le provider OraOLEDB.Oracle.1 et pour ce qui est système je travaille sous windows 2003/2008 64 bits.
Pour faire simple, coté client j'envoi des trames que je décode coté serveur pour ensuite effectuer des actions toujours coté serveur.
Voici l'architecture simplifié du serveur :
- Un DataModule dans lequel se trouve mon TADOConnection.
- Une classe de type TForm dans lequel se trouve mes fonctions génériques et qui contient une variable public de type TDataModule ainsi qu'un bon nombre de TADOQuery.
- Des classes de type TForm dans lequel je fais des traitements spécifiques et qui contient aussi des TAdoQuery.
- Ma classe de type TThread.
Concernant ma classe TThread, voici mon constructeur Thread.Create()
Ensuite dans mes classes spécifiques voici comment je gère mes transactions :
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
33 constructor ClassThread.Create( ); begin // general inits inherited Create(true); try DataModule1 := TDataModule.Create(nil); except On E : Exception do begin TraceErreurFichier( E.Message ); end; end; // Classes pour mes traitements spécifiques ClassSpe1 := TClassSpe1.Create(nil); ClassSpe2 := TClassSpe2.Create(nil); ClassSpe3 := TClassSpe3.Create(nil); // Classe générique dans lequel je fais des traitements réutilisable dans les autres classes ClassGene := TClassGene.Create(nil); // J'ai une variable public de type TDataModule1 dans la classe ClassGene ce qui me permet d'avoir une connexion TADOConnection par thread. ClassGene.DataModule1 := DataModule1; // Ensuite je passe ma classe générique à mes classes spécifique afin que je puisse utiliser mes fonctions génériques et tout ce qui est lié à ma TADOConnection. ClassSpe1.ClassGene := ClassGene; ClassSpe2.ClassGene := ClassGene; ClassSpe3.ClassGene := ClassGene; resume; end;
J'utilise également des évenements de la TADOConnection afin de tracer certaines choses, notamment :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 // Ouverture if not ClassSpe1.DataModule1.BD.InTransaction then ClassSpe1.DataModule.BD.BeginTrans; // Commit if ClassSpe1.DataModule1.BD.InTransaction then ClassSpe1.DataModule.BD.Commit; // RollBack if ClassSpe1.DataModule1.BD.InTransaction then ClassSpe1.DataModule.BD.Rollback;
- BDBeginTransComplete
- BDCommitTransComplete
- BDRollbackTransComplete
et j'ai ces logs dans mon fichier qui me permette de voir ce qu'il se passe :
[18] étant le numéro de mon thread et 410 la méthode ou je me trouve.<22/05/2012 10:12:25.160> [18]: Debut transaction : 410 => Transaction level : 1
<22/05/2012 10:12:25.187> [18]: Commit transaction : 410
Et c'est là que mon problème intervient. Parfois et de façon complétement aléatoire les transactions partent en sucette :
Et voici ce que me donne l'objet Error remonté dans le BDCommitTransComplete :<22/05/2012 10:12:46.206> [18]: Debut transaction : 410 => Transaction level : 9004
J'ai parfois également des erreurs du genre : "No Transaction Active" alors que devant tout mes commits, rollback et begintrans je teste si j'ai une transaction est déjà ouverte (voir exemple du début).<22/05/2012 10:12:46.206> [18]: Erreur => Number : -2147467259 => Source : Provider => Description : Erreur non spécifiée SQLState => => Description :
je me suis aussi rendu compte que lorsque mon commit échoue comme ci-dessus mon flag InTransaction du TADOConnection repasse à False comme c le commit avait fonctionné.
Du coup lorsque j'arrive à nouveau sur une ouverture de transaction, je vois qu'il n'y a pas de transaction ouverte donc j'essaie dans ouvrir une autre et à ce moment là mon BDBeginTransComplete me renvoie l'erreur suivante :
Pour l'instant j'arrive à parer le problème en forçant un commit coûte que coûte afin de fermer la transaction correctement mais ce n'est pas très propre et je ne suis pas sûr que cela résolve tous mes problèmes.Erreur => Number : -2147168237 => Source : OraOLEDB => Description : Impossible de démarrer d'autres transactions pour cette session. SQLState => Description :
J'attends vos retours sur ce problème ainsi que votre aide avec impatience....
Partager