Durchsuchbare Dokumentation aufrufen

Zurück zur Dokumentationsübersicht

JavaScript-Bibliothek common/transaction

Diese Bibliothek bietet Funktionen zum Ablaufen von Modifikationen in Transaktionen.

Regeln für Transaktionen


Beispiel: agorum core schickt Daten per API an DATEV oder an eine andere Schnittstelle. Tauchen währenddessen im Workflow oder im ausführenden Skript Fehler auf, rollt agorum core die Transaktion zwar zurück, das Fremdsystem jedoch nicht. Das kann dazu führen, dass doppelt oder falsch gebucht wird. Planen Sie den Prozess so, dass diese Fehler nicht in der gleichen Transaktion stattfinden, oder entwickeln Sie ein Konzept, um der API mitzuteilen, dass die Daten ungültig sind.

Verwendung


Binden Sie die Bibliothek stets am Anfang eines Skripts ein:

let transaction = require('common/transaction');

Aufruf


transaction(timeout, (t) => callback(t));

Parameter

Parameter Beschreibung Standard
timeout Definiert in Sekunden, wie lange die Transaktion maximal dauern darf.

Wenn diese Zeit abgelaufen ist, wird die Transaktion abgebrochen und es wird ein Rollback ausgeführt.
-1  (Time-out wird nicht berücksichtigt, die Transaktion kann beliebig lange laufen.)
callback Definiert die zu übergebene Funktion, die innerhalb der Transaktion ausgeführt wird.
  • Läuft diese Funktion ohne Fehler durch, wird am Ende automatisch ein Commit durchgeführt. Wird ein Fehler geworfen, so wird stattdessen ein Rollback durchgeführt.​​​​​​
  • Der Funktion wird als Parameter eine Referenz auf das Transaktions-Objekt übergeben. Für kleinere Transaktionen ist dieses typischerweise nicht nötig, aber bei der Verarbeitung von größeren Datenmengen muss die Transaktion regelmäßig über t.restart() neu gestartet werden.

    Hinweis: Rollen Sie die Transaktion nicht manuell zurück, sondern verwenden Sie den automatischen Rollback, indem ein geeigneter Fehler per throw geworfen wird. Nur so ist sichergestellt, dass der Transaktionsblock nach dem Rollback korrekt verlassen wird.

Folgende Funktionen bietet der Parameter t an:

restart
Führt einen Commit aus und startet sofort eine neue Transaktion. Es existieren keine weiteren Parameter für restart.


Allgemein mit Time-out in Millisekunden (ms)

let obj = require('common/objects'),
    transaction = require('common/transaction');

let timeout = 300; // Maximal 5 Minuten

transaction(timeout, t => {
  // Alles was hier drin abläuft wird in einer Transaktion gemacht
});


Allgemein ohne Time-out

Der Time-out wird auf den Standard -1 gesetzt.

let transaction = require('common/transaction');

transaction(t => {
  // Alles, was hier drin abläuft, wird in einer Transaktion gemacht
});

Beispiele


Beispiel 1

Nachfolgendes Beispiel zeigt eine Iteration über alle Objekte, bei der der Name eines jeden gefundenen Objekts umgesetzt wird. Es werden immer 50 Objekte in einer Transaktion umgesetzt.

let obj = require('common/objects');
let transaction = require('common/transaction');

function forEach(query, threshold, callback) {
  transaction(t => {
    let c = 0;

    obj.query(query).forEach(object => {
      if (++c > threshold) {
        t.restart();
        c = 0;
      }

      callback(object);
    });
  });
}

let ret = [];

forEach('name:("Dokumente" NOT "Sonstige_Dokumente") area:(Vorgangsdokumente NOT "Vorgangsdokumente - Ablage")', 50, object => {
  object.name = "Sonstige_Dokumente";
  ret.push(object.ID);
});

ret;

Beispiel 2

Nachfolgendes Beispiel zeigt, wie jede Änderung innerhalb einer Schleife als einzelne Transaktion durchgeführt wird.

// Delete DocumentTextObjects
// Unten in den Aufruf: clear(..) das entsprechende Suchmuster einstellen.
// Mit diesem Script kann das selbe gemacht werden wie unter desk4web Tooles 'Delete Document Text of objects'

let IndexHelper = Packages.agorum.roi.searchengine.IndexHelper;
let MessageUtils = Packages.agorum.roi.ejb.messaging.common.MessageUtils;
let MessageBean = Packages.agorum.roi.ejb.messaging.common.MessageBean;

let objects = require('common/objects');
let transaction = require('common/transaction');

function clear(query) {
  let count = 0;
  let mu = new MessageUtils();

  objects.query(query).forEach(object => {
    transaction(() => {
      IndexHelper.disableRealtimeIndex();

      object.deleteDocumentText();

      let mb = new MessageBean();

      mb.setObjectProperty('value', new java.lang.Long(object.getId()));
      mb.setObjectProperty('eventType', 'updateObjectListener');
      mb.setObjectProperty('className', object.className);
      mb.setObjectProperty('NoEventAssistanceObject', '');

      mu.publishToTopic('updateObjectListener', mb, true);

      ++count;
    });
  });

  return count;
}

clear('nameextension:(html OR htm OR txt OR json OR xml)');

Beispiel 3

Nachfolgendes Beispiel zeigt, wie Sie eine Transaktion nach einer gewissen Zeit und nicht nach x Durchgängen neu starten.

let transaction = require('common/transaction');

// Definiere die Abbruchfunktion
// nach x Sekunden wird der übergebene callback ausgeführt
let periodic = (period, fn) => {
  let next = Date.now() + period;

  return () => {
    if (Date.now() > next) {
      fn();
      next = Date.now() + period;
    }
  };
};

transaction(t => {
  // ...

  // Definiere genaue Funktion, in dem Fall wird bei jedem Transaktionsneustart auch ein flush auf ein Logfile ausgeführt
  // Die Periode wird auf 30 Sekunden gesetzt
  let auto = periodic(30 * 1000, () => {
    ow.flush();
    t.restart();
  });

  // z. B. Schleife oder forEach
  // In dieser Schleife wird regelmäßig geprüft, ob die Zeit um ist und erneut ausgeführt werden muss
  while (...) {

    // ...
    auto();
    // ...
  }
});

Beispiel 3

Nachfolgendes Beispiel zeigt, wie Sie eine Transaktion zurückrollen.

transaction(t => {
  // Alles, was hier drin abläuft, wird in einer Transaktion gemacht

  throw new Error('Transaktion beenden und rollback machen');
});