Wie wird das Überspringen in Spring Batch implementiert?

8

Ich habe mich gefragt, wie ich in meinem ItemWriter feststellen konnte, ob Spring Batch gerade im Chunk-Processing-Modus oder im Fallback-Single-Item-Processing-Modus war. An erster Stelle fand ich nicht die Information, wie dieser Fallback-Mechanismus ohnehin implementiert wird.

Auch wenn ich die Lösung meines eigentlichen Problems noch nicht gefunden habe, möchte ich mein Wissen über den Fallback-Mechanismus mit Ihnen teilen.

Fühlen Sie sich frei, Antworten mit zusätzlichen Informationen hinzuzufügen, wenn ich etwas verpasst habe; -)

    
Peter Wippermann 15.05.2013, 14:12
quelle

2 Antworten

11

Die Implementierung des Skip-Mechanismus finden Sie in FaultTolerantChunkProcessor und in der RetryTemplate .

Nehmen wir an, Sie haben überspringbare Ausnahmen konfiguriert, aber keine wiederholbare Ausnahmen . Und es gibt ein fehlerhaftes Element in Ihrem aktuellen Chunk, das eine Ausnahme verursacht.

Nun soll zuerst der ganze Brocken geschrieben werden. In der write() Methode des Prozessors können Sie sehen, dass ein RetryTemplate aufgerufen wird. Es erhält auch zwei Referenzen auf ein RetryCallback und ein RecoveryCallback .

Wechseln Sie zu RetryTemplate . Finde die folgende Methode:

%Vor%

Dort können Sie sehen, dass RetryTemplate erneut versucht wird, solange es nicht erschöpft ist (d. h. genau einmal in unserer Konfiguration). Ein solcher Wiederholungsversuch wird durch eine retryable exception verursacht. Nicht wiederholbare Ausnahmen werden den Wiederholungsmechanismus sofort abbrechen.

Nachdem die Wiederholungen erschöpft oder abgebrochen sind, wird der RecoveryCallback aufgerufen:

%Vor%

Das ist der Punkt, an dem der Single-Item-Bearbeitungsmodus jetzt einsetzt!

Der RecoveryCallback (der in der write() -Methode des Prozessors definiert wurde!) wird den Eingabeklotz sperren ( inputs.setBusy(true) ) und die scan() -Methode ausführen. Dort können Sie sehen, dass ein einzelner Gegenstand aus dem Brocken genommen wird:

List<O> items = Collections.singletonList(outputIterator.next());

Wenn dieses einzelne Element von ItemWriter korrekt verarbeitet werden kann, wird das Chunk beendet und das ChunkOrientedTasklet wird einen weiteren Chunk (für die nächsten einzelnen Elemente) ausführen. Dies führt zu einem regelmäßigen Aufruf von RetryCallback , aber da der Chunk von RecoveryTemplate gesperrt wurde, wird die Methode scan() sofort aufgerufen:

%Vor%

Es wird also ein anderer einzelner Artikel verarbeitet und dies wird wiederholt, bis der ursprüngliche Chunk Stück für Stück bearbeitet wurde:

%Vor%

Das ist es. Ich hoffe, Sie fanden das hilfreich. Und ich hoffe noch mehr, dass Sie dies leicht über eine Suchmaschine finden können und nicht zu viel Zeit verschwenden, um das selbst herauszufinden. ; -)

    
Peter Wippermann 15.05.2013, 14:12
quelle
1

Eine mögliche Annäherung an mein ursprüngliches Problem (der ItemWriter würde gerne wissen, ob es im Chunk- oder Single-Item-Modus ist) könnte eine der folgenden Alternativen sein:

  • Nur wenn der übergebene Chunk die Größe 1 hat, müssen weitere Checks gemacht werden
  • Wenn der übergebene Chunk ein java.util.Collections.SingletonList ist, wären wir ziemlich sicher, da FaultTolerantChunkProcessor folgendes tut:

    Listenelemente = Collections.singletonList (outputIterator.next ());

    Leider ist diese Klasse privat und wir können sie nicht mit instanceOf überprüfen.

  • Umgekehrt, wenn der Chunk ein ArrayList ist, könnten wir auch ziemlich sicher sein, da die Chunk -Klasse des Spring Batches sie verwendet:

    private Listenelemente = new ArrayList ();

  • Eine Unschärfe links wären gepufferte Objekte, die aus dem Ausführungskontext gelesen werden. Aber ich würde erwarten, dass dies auch ArrayLists sind.

Jedenfalls finde ich diese Methode immer noch zu vage. Ich möchte diese Informationen lieber durch das Framework zur Verfügung stellen.

Eine Alternative wäre, meinen ItemWriter in der Framework-Ausführung zu haken. Vielleicht ist ItemWriteListener.onWriteError() angemessen.

Aktualisierung: Die Methode onWriteError() wird nicht aufgerufen, wenn Sie sich im Einzelelementmodus befinden und eine Ausnahme in ItemWriter auslösen. Ich denke, das ist ein Fehler, den es eingereicht hat: Ссылка

Also diese Alternative fällt aus.

Hier ist ein Ausschnitt, um das gleiche zu tun, ohne irgendwelche Framework-Mittel direkt im Schreiber

%Vor%

Achtung: Man sollte hier lieber nach den überspringbaren Ausnahmen suchen und nicht nach Exception im Allgemeinen.

    
Peter Wippermann 15.05.2013 14:39
quelle

Tags und Links