Ein Batch, der einfach durchläuft, kann trotzdem fachlich falsch sein. Genau deshalb brauchen wir Datenqualität als erstklassiges Ziel, nicht als Nachgedanken. Datenqualität heißt: Die Daten sind vollständig, gültig, eindeutig und konsistent. In diesem Teil definieren wir Qualitätsregeln und behandeln Duplikate, Referenzen und Late Data. Außerdem bauen wir einen klaren Prüfpfad.
Zielbild
Nach diesem Kapitel kannst du Datenqualitätsregeln explizit machen, Duplikate und Referenzprobleme gezielt behandeln und einen Prüfpfad definieren, der messbar und auditierbar ist.
Qualitätsdimensionen (Kurzlandkarte)
Die Qualitätsdimensionen sind Vollständigkeit, Gültigkeit, Eindeutigkeit,
Konsistenz und Aktualität. Beispiel: Eine fehlende E-Mail verletzt
Vollständigkeit, zwei gleiche customer_id verletzen Eindeutigkeit.
Prüfpfad: Staging statt Direktimport
Ein robustes Muster ist:
- Rohdaten in eine Staging-Tabelle schreiben.
- Qualitätschecks und Bereinigung.
- Fachliche Zieltabellen befüllen (idempotent).
Staging heißt: Rohdaten landen zuerst in einer Zwischentabelle. So kannst du die Rohdaten auditieren, ohne sofort produktive Tabellen zu beschädigen. Gerade bei CSV-Imports ist das Gold wert.
Staging hat noch einen zweiten Effekt: Restartability wird eindeutig.
Wenn du eine run_id für den Import nutzt und alle Rohdaten mit dieser
run_id markierst, liest der Job beim Restart exakt denselben Input.
Bei mutierenden DB-Quellen ist das der sicherste Weg, um Lücken und Duplikate
zu vermeiden.
Warum das bei DB-Readern entscheidend ist und welche Alternativen es gibt,
finden wir in
Teil 6: JobParameters & Restartability.
Beispiel-Schema für Staging (auf unsere CSV-Domäne zugeschnitten):
staging_customers(
run_id UUID,
source_file VARCHAR(255),
line_number BIGINT,
customer_id BIGINT,
first_name VARCHAR(100),
last_name VARCHAR(100),
email VARCHAR(255),
birth_date DATE,
signup_date DATE,
loaded_at TIMESTAMP,
parse_status VARCHAR(16)
)
Quarantine/Rejects: Fehler sichtbar halten
Fehlerhafte Datensätze willst du nicht verlieren. Lege sie in eine separate Reject-Tabelle ab, damit du sie auditieren, korrigieren oder reprocessen kannst. Eine einfache Struktur:
staging_customer_rejects(
run_id UUID,
source_file VARCHAR(255),
line_number BIGINT,
raw_payload VARCHAR(4000),
error_code VARCHAR(32),
error_message VARCHAR(255),
rejected_at TIMESTAMP
)
So bleibt jeder Fehler sichtbar und du kannst eine fachliche Entscheidung treffen, statt nur einen Skip-Count zu sehen.
Duplikate: fachlich entscheiden
Duplikate sind kein technisches Detail, sondern eine Geschäftsregel. Für unseren Import könnten Regeln so aussehen: customer_id ist eindeutig bedeutet, dass ein Duplikat je nach Schwere zu Fail oder Skip führt. E-Mail doppelt kann eine Warnung mit Skip sein, aber nicht fatal. Gleicher Datensatz erneut sollte idempotent behandelt werden und ist kein Fehler.
Wichtig: Du musst vorab entscheiden, welche Duplikate tolerierbar sind.
Referenzen: Konsistenz zwischen Tabellen
Beispiele: Ein Kunde darf nur existieren, wenn seine country_code bekannt
ist. Ein Report darf nur erzeugt werden, wenn alle Kunden geschrieben wurden.
In der Praxis heißt das: Referenzdaten zuerst laden, Foreign Keys in
der DB erzwingen, wo sinnvoll, und Staging-Checks für fehlende Referenzen
einbauen. Beispiel: Ein Kunde ohne gültigen country_code wird im Check
geblockt.
Konkrete Checks (SQL-Skizzen)
Ein paar einfache Checks, die du direkt auf Staging fahren kannst:
-- Duplikate nach customer_id
select customer_id, count(*)
from staging_customers
where run_id = :runId
group by customer_id
having count(*) > 1;
-- Fehlende Referenzen (country_code nicht bekannt)
select s.customer_id
from staging_customers s
left join ref_country c on c.code = s.country_code
where s.run_id = :runId and c.code is null;
-- Ungültige Datumsfelder (Signup in der Zukunft)
select customer_id
from staging_customers
where run_id = :runId and signup_date > current_date;
Diese Checks kannst du als eigene Steps oder als Tasklet vor dem eigentlichen Import ausführen. Wichtig ist: Fehler müssen vor dem Write sichtbar sein.
Late Data: verspätete Korrekturen
In der Realität kommen Daten oft verspätet oder korrigiert. Beispiele sind nachträglich ergänzte Kundendaten, korrigierte E-Mails oder rückwirkend gelieferte historische Datensätze.
Strategien sind ein Reprocessing-Fenster definieren, etwa 7 Tage rückwärts, Upserts (Insert oder Update) statt Inserts für korrigierbare Felder und ein Staging-Hash (Hash über die Rohzeile) zum Erkennen von Änderungen. Beispiel: Eine Adresse kommt 3 Tage später korrigiert, das Reprocessing-Fenster nimmt sie mit.
Ohne klare Regel läufst du in Endlosschleifen: jeder Run schreibt andere Daten, ohne dass du den Ursprung kennst.
Qualitätskennzahlen als KPI
Datenqualität wird erst steuerbar, wenn du Kennzahlen hast. Beispiele:
- Reject-Rate = rejects / input
- Duplicate-Rate = duplicateRows / input
- Missing-Ref-Rate = missingRefs / input
Damit kannst du Trends erkennen. Beispiel: Heute doppelt so viele Rejects ist ein operatives Signal und gehört ins Monitoring.
Reconciliation: Zahlen müssen passen
Ein Batch ist fachlich nur korrekt, wenn sich die Zahlen erklären lassen. Reconciliation heißt: Zähler werden gegeneinander abgeglichen. Input-Count muss dem Read-Count entsprechen, Output-Count dem Write-Count, und Rejected/Skipped müssen dokumentiert sein.
Typischer Audit-Satz für einen Run:
input=100000, written=99500, skipped=500, failed=0
Diese Kennzahlen liefert Spring Batch automatisch über die
StepExecution-Zähler: getReadCount(), getWriteCount(),
getSkipCount() und getCommitCount(). Du kannst sie z. B. in einem
StepExecutionListener auslesen und loggen oder an ein Monitoring-System
senden. Einsteiger-Tipp: Wenn readCount und input nicht zueinander passen,
stimmt der Importpfad nicht.
Artefakt: Datenqualitäts-Checkliste
Minimal-Checkliste für unseren Import:
- [ ] Pflichtfelder geprüft (customer_id, email)
- [ ] Datumsfelder validiert (ISO, keine Zukunftsdaten)
- [ ] Dedupe-Regel definiert (customer_id eindeutig)
- [ ] Referenzen geprüft (country_code bekannt)
- [ ] Staging-Rohdaten gespeichert
- [ ] Reconciliation-Zahlen dokumentiert
- [ ] Late-Data-Strategie festgelegt
Anti-Patterns
Direkt in Zieltabellen schreiben verhindert Auditbarkeit. Duplikate still überschreiben bedeutet Datenverlust ohne Nachweis. Keine Reconciliation macht Erfolg nicht belegbar. Late Data ignorieren führt zu inkonsistenten Reports.
Zusätzlich riskant: DB-Reader ohne Snapshot/Cutoff machen Restarts nicht deterministisch.
Kurzfazit
Datenqualität ist Betriebsarbeit, nicht nur Validierung. Staging und Reconciliation machen Qualität messbar. Ohne Regeln für Duplikate und Late Data wird jeder Run unsicher.
Im nächsten Teil geht es um Performance-Grundlagen: Chunk-Größe, Fetch-Size und Batch-Writes und wie du Engpässe systematisch findest.
Alle Teile der Serie: Serie: Spring Batch