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 :

batch-problem.png

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-20px.png 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 :

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;
Tip-20px.png Tip : Notez l'utilisation de LOI pour tester la fin du curseur dans la boucle du foreach
Outils personnels