3.5 KiB
Was eine UI-Störung im Protokoll nennen darf
Am 2026-10-21 scheiterte in Produktion jeder Schreibvorgang. Im Journal stand dazu genau eine Zeile:
UI failure 7f3a21c4 (org.h2.jdbc.JdbcSQLNonTransientConnectionException)
Mehr gab es nicht. UiErrorConfiguration protokollierte die Klasse der untersten Ursache und sonst
nichts — bewusst, denn Exception-Meldungen können SQL-Werte oder Nutzertext enthalten. Die
Zurückhaltung war richtig, die Auswahl zu eng: eine Klasse allein unterscheidet keine zwei
Datenbankfehler voneinander.
Warum die Klasse allein nicht reicht
Die Untersuchung zu H2-Verbindungslebenszyklus musste die Ursache aus genau dieser einen Zeile rekonstruieren. Dabei trat zutage, wie viel an Information fehlte:
- Der SQLState hilft bei H2 nicht weiter, wo man ihn vermuten würde. H2 2.4.240 vergibt für seine
90xxx-Fehler den Fehlercode selbst als SQLState.
DATABASE_IS_CLOSEDmeldetsqlState=90098, nicht eine 08er-Verbindungsklasse. Aus der Exception-Klasse auf eine SQLState-Klasse zu schließen, führt in die Irre; der Treibercode ist die Angabe, die trennt. - Die Exception-Klasse fasst sehr Verschiedenes zusammen.
JdbcSQLNonTransientConnectionExceptionsteht unter anderem fürDATABASE_IS_CLOSED(90098),OUT_OF_MEMORY(90108),FILE_CORRUPTED_1(90030) undDATABASE_CALLED_AT_SHUTDOWN(90121) — Zustände mit völlig verschiedenen Konsequenzen für den Betrieb. - Die Kette trennt, was die unterste Klasse verbirgt. Ein erschöpfter Heap erreicht die Anwendung
als
JdbcSQLNonTransientConnectionExceptionmitjava.lang.OutOfMemoryErrordarunter; ein Schreibfehler der Ablage alsJdbcSQLNonTransientExceptionüber einemMVStoreExceptionoderIOException. Nur die Kette zeigt diesen Unterschied.
Die Rekonstruktion kam damit bis zu einer Aussage über die Form der Exception und blieb dort stehen. Mit den Angaben dieser Umsetzung wäre sie eine Zuordnung gewesen.
Was die Zeile jetzt nennt
failureDetail setzt die Zeile aus der Kette der Exception-Klassen zusammen und ergänzt bei einem
Datenbankfehler sqlState und errorCode des Treibers:
UI failure 7f3a21c4 (java.lang.RuntimeException <- org.jooq.exception.DataAccessException
<- org.h2.jdbc.JdbcSQLNonTransientConnectionException sqlState=90098 errorCode=90098)
Meldungen bleiben weiterhin draußen. Das war der Grund der ursprünglichen Zurückhaltung und gilt unverändert: Klassennamen, SQLState und Fehlercode sind Werte des Treibers, keine Werte aus den Daten. Die Fehlerkennung, die der Nutzer sieht, bleibt unverändert die Brücke zwischen Meldung und Protokollzeile.
Genommen wird die letzte SQLException der Kette, nicht die erste: Spring und jOOQ hüllen den
Treiberfehler in eigene SQLException-Ableitungen, deren Code und Zustand nichts aussagen. Ohne
Datenbankfehler in der Kette nennt die Zeile nur die Klassen.
Die Kette ist weiterhin auf sechzehn Glieder begrenzt, wie schon zuvor beim Suchen nach
RecordConflict und RecordNotFound. Für die beobachteten Ketten reicht das deutlich.
Nachweise
FailureDetailTest: ein Datenbankfehler in der Form des Vorfalls vom 2026-10-21 nenntsqlState=90098,errorCode=90098und beide umhüllenden Klassen, und weder die SQL-Anweisung noch die darin enthaltene Adresse erscheinen in der Zeile; wo H2 Code und Zustand auseinanderhält (ERROR_OPENING_DATABASE_1,08000/8000), werden beide getrennt gelesen; eine Störung ohne Datenbankursache nennt nur ihre Klassen.