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; -)
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:
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:
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:
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. ; -)
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:
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 ();
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.
Tags und Links spring-batch skip chunks fallback