Transaction longue partagée (parallel)

De Wiki1000

Les transactions longues peuvent être partagées sous réserve de ne pas exécuter de BatchLongTran à l'intérieur du code parallélisé.

En effet l'exécution d'un batch doit être synchronisé avec le code métier pour éviter de mettre à jour des objets dans un état incohérent.

A défaut le scénario suivant peut se produire :

{{#images:batch-problem.png|dsm/parallel}}

Dans ce scénario :

  • Le code crée un objet puis le modifie en plusieurs étapes avant d'appeler BatchLongTran.
  • L'exécution du batch par l'exécution parallèle (worker2) met à jour un objet en cours de création (worker1) dans un état incohérent.

Le comportement des patterns de code vis à vis des transactions longues est le suivant :

ForEachP with long(BatchSize) transaction

Ce pattern exécute BatchLongTran à l'intérieur de sa boucle, vous n'avez pas besoin d'appeler explicitement BatchLongTran.

WithP long(BatchSize) transaction

Ce pattern n'appelle pas BatchLongTran et vous devez appeler explicitement BatchLongTran à l'extérieur du code parallélisé.
Tip :
  • Un appel à BatchLongTran est ignoré si le nombre d'objet dans la transaction est inférieur à la taille du batch (BatchSize)
  • Un appel à BatchLongTran depuis du code parallélisé est ignoré.

Une transaction longue partagée :

<source lang="delphi"> procedure doProcessList(ls:ClassCList); var inst:ClassC; begin

 foreach inst in ls do
  inst.unBool := True;

end;

function TestForEachParallelLongTran:Integer; var inst:ClassC; list:ClassCList; cursor:ClassCCursor; count:Integer; begin

 List := ClassC.CreateList;
 Cursor := ClassC.CreateCursorWhere(,,true,[]);
 foreachP inst in cursor index count with long transaction do
   begin
     List.AddRef(inst);
     if cursor.LOI or (List.Count=100) then
      begin
        parallel doProcessList(List);
        List.Clear;
      end;
   end;
 Result := 1+count;

end; </source>

Tip : Notez l'utilisation de LOI pour tester la fin du curseur dans la boucle du foreach