Lade...
 

iterate und Transaktionen

Beenden und Start einer Transaktion innerhalb eines Iterate-Zyklus

Um das Concurrency-Verhalten zu verbessern (oder um Address-Space freizugeben) kann es sinnvoll sein, innerhalb einer Iterationsschleife eine Transaktion zu beenden und eine neue zu starten.

Wichtig!
Dies ist nur innerhalb von Schleifen mit Iterate(UNSAFE) möglich, nicht innerhalb eines normalen Iterate! Dies gilt nur für die Iteration über Collections, nicht bei Vektoren.

Bei der Iteration über eine Collection mit persistenten Objekten als Elemente muss am Ende des Iterations-Zyklus, also vor dem "Weiterrücken" zum nächsten Element eine Datenbank-Transaktion aktiv sein.

Beispiele

Dies ist verboten und führ zu undefiniertem Verhalten:

FindAll(CX_ITEM) iterate
{
   -> object
   . . .  // some processing
   EndTXN // commit transaction
   . . .  // some more processing
}

Nur mit Iterate(UNSAFE) ist der Neustart einer Transaktion erlaubt (es ist jedoch darauf zu achten, dass am Ende des Blocks eine Transaktion läuft):

FindAll(CX_ITEM) iterate(UNSAFE)
{
   -> object
   . . .  // some processing
   Index 1000 Mod 0 = if { EndTXN BeginTXN } // new transaction after processing of 1000 objects
}

Das Beenden der Transaktion betrifft alle Iterate-Schleifen, daher ist auch folgendes verboten (hier wird das äußere Iterate zu einem undefinierten Verhalten führen, obwohl sich das EndTXN innerhalb eines Iterate(UNSAFE) befindet):

FindAll(CX_ITEM) iterate
{
  Get(monitors) iterate(UNSAFE)
  {
     -> object
     Index 1000 Mod 0 = if { EndTXN BeginTXN } // new transaction after processing of 1000 objects
     . . .  // some processing
  }
}

Hier wird die Transaktion nicht durch ein explizites BeginTXN neu gestartet, sondern die Copy-Anweisung startet implizit (automatisch) eine neue Transaktion:

FindAll(CX_ITEM) iterate(UNSAFE)
{
   -> object
   Index 1000 Mod 0 = if EndTXN  // new transaction after processing of 1000 objects
   object Copy(uniqeID) // Copy will restart a transaction automatically
   . . .  // some more processing
}

In diesem Fall wird keine Transaktion gestartet und es gibt einen Fehler:

FindAll(CX_ITEM) iterate(UNSAFE)
{
   -> object
   object Copy(uniqeID) 
   . . .  // some processing
   Index 1000 Mod 0 = if EndTXN   // new transaction after processing of 1000 objects
}

Bei der Iteration über Vektoren kann man sich auf den automatischen Neustart einer Transaktion verlassen (das Iterate selbst benötigt in diesem Falle keine Transaktion und wird auch nicht durch das Beenden einer Transaktion innerhalb der Schleife beeinträchtigt):

FindAll(CX_ITEM) GetVector iterate(UNSAFE)
{
   -> object
   object Copy(uniqeID) // Copy will restart a transaction automatically
   . . .  // some processing
   Index 1000 Mod 0 = if EndTXN   // new transaction after processing of 1000 objects
   . . .  // some more processing
}