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()
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;
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
 
// 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;
J'utilise également des évenements de la TADOConnection afin de tracer certaines choses, notamment :
- BDBeginTransComplete
- BDCommitTransComplete
- BDRollbackTransComplete
et j'ai ces logs dans mon fichier qui me permette de voir ce qu'il se passe :
<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
[18] étant le numéro de mon thread et 410 la méthode ou je me trouve.

Et c'est là que mon problème intervient. Parfois et de façon complétement aléatoire les transactions partent en sucette :
<22/05/2012 10:12:46.206> [18]: Debut transaction : 410 => Transaction level : 9004
Et voici ce que me donne l'objet Error remonté dans le BDCommitTransComplete :
<22/05/2012 10:12:46.206> [18]: Erreur => Number : -2147467259 => Source : Provider => Description : Erreur non spécifiée SQLState => => Description :
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).

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 :
Erreur => Number : -2147168237 => Source : OraOLEDB => Description : Impossible de démarrer d'autres transactions pour cette session. SQLState => Description :
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.

J'attends vos retours sur ce problème ainsi que votre aide avec impatience....