Fehler Transaktion in Middleware?

Hallo @all!

Bei Testläufen zu einem Programm hakt es bei einer Transaktion. Ich habe darauf
das Logging ausgedehnt und erhalte als Letztes folgende Zeilen.

LOCATION:  LogCheckpointStart, xlog.c:6236
LOG:  00000: checkpoint complete: wrote 452 buffers (11.0%); 0 transaction log file(s) added, 0 removed, 0 recycled;
write=91.048 s, sync=0.168 s, total=91.272 s
LOCATION:  LogCheckpointEnd, xlog.c:6282

Ich interpretiere die Zeilen so, dass gerade einmal 11% der Transaktion in 91 sek. geschrieben wurden.

Daraufhin habe ich die Transaktion im psql per Hand eingetippt und die gesamte Transaktion funktioniert einwandfrei. Kann ich dies so interpretieren, dass es kein Problem der Datenbank ist, sondern der Fehler eher im Programm oder in der Middleware zu suchen ist?

Was genau bedeutet bei dir “es hakt bei einer Transaktion”? Hast du eine konkrete Fehlerbeschreibung oder gar eine Fehlermeldung?

Die von dir gepasteten Zeilen wirst du häufiger im Log finden, das ist ein komplettierter Checkpoint. Der hat mit deiner Anwendung eigentlich nichts zu tun (außer du löst manuell einen Checkpoint aus).

Ergänzend zu ads:

Du könntest mal loggen, was die Anwendung an SQL liefert und ob dies das ist, was Du erwartest bzw. händisch in psql getestet hast.


Andreas

Was genau bedeutet bei dir “es hakt bei einer Transaktion”? Hast du eine konkrete Fehlerbeschreibung oder gar eine Fehlermeldung?

Ich bin bei eclipse im Debug-Modus und erhalte keine Rückmeldung mehr. Es passiert einfach gar nichts. Die genaue Stelle, wo er stehen bleibt habe ich noch nicht herausgefunden. Mein Programm übergibt an jDBI, jDBI übergibt an commons DBCP, das wiederum an postgresql-JDBC. Wann es genau stoppt, will ich noch heraufinden. Aber dazu muss ich das postgresql.jar noch mit Sourcen versehen, damit sie auch von eclipse im Debug-Modus angezeigt werden. Gestern Abend war es dafür zu spät.

Das ganze passiert mir bei Junit-Tests. Die Datenbank hat minimalen Datenbestand.

Du könntest mal loggen, was die Anwendung an SQL liefert und ob dies das ist, was Du erwartest bzw. händisch in psql getestet hast.

Habe ich gemacht. Die Anwendung liefert genau das, was ich erwartet habe. Aus dem Logfile habe ich die Daten händisch in psql eingetragen, wo alles einwandfrei lief.

Merkst du was? Da ist zuviel Middleware im Spiel. Und bei einem Fehler suchst du nicht an einer Stelle sondern an einem Dutzend.

Vor allem, da du ja schon festgestellt hast, dass die eigentliche Operation wie gewünscht in der Datenbank funktioniert. Bleibt nun also die gesamte Zwischenschicht übrig zum Debuggen …

Merkst du was? Da ist zuviel Middleware im Spiel. Und bei einem Fehler suchst du nicht an einer Stelle sondern an einem Dutzend.

Zuviel Middleware? Das ist Geschmacksache. jDBI ist eine kleine Sammlung, die das Handling von SQL erheblich vereinfacht. commons DBCP braucht man meines Erachtens, um im JEE Umfeld connection pool zu verwalten. Den postgres-JDBC-Treiber braucht man zur Anbindung an die Datenbank.

Natürlich kann ich auch auf alles verzichten und alles selbst (noch mal neu) entwickln. Dann wird es aber nicht einfacher.

Ich sehe ein, dass Middleware im Stile von Hibernate problematisch ist. Aber so etwas verwende ich nicht. Was wäre denn deiner Meinung nach zu ersetzen?

Nichts. Dir gefällt das, damit ist das gut.
Du musst halt jetzt nur den Fehler finden :wink:

Ich habe alles debuggt und das Programm hing beim Einlesen aus einem IO-Stream. Aufgrund mener Annahme, dass die Middleware grds. funktioniert, habe ich dann in meinem Programm experimentiert.

Ausgangslage war: In Klasse 1 wurde Update auf Tabelle A durchgeführt.
Dann folgten in Klasse 2 ein Insert B und ein Insert C. Beim Insert C wurde auch der Primary-Index-Wert vom Update von Tabelle A verwendet.

Als ich die Transaktionsstatements entfernt hatte, lief alles durch. Als ich Insert C von Klasse 2 in Klasse 1 verschoben hatte lief auch alles als Transaktion. Ich habe das so gewertet, dass sich Update und Insert in verschiedenen Klassen nicht vertragen.

Daraufhin habe ich in der Transaktion die Reihenfolge geändert. Erst Insert B und Insert C in Klasse 2, dann Update A in Klasse 1. So lief es auch. Damit kann ich gut leben.

Aalso … für mich hört sich das nach konkurierenden Transaktionen an … als mein kleiner niedlicher Connection-Pool noch in den Kinderschuhen steckte hatte ich damit auch mal so meine Probleme …

Wenn es mal wieder “hakt” solltest du mal mit einem PG admin client etc. die Client-/Prozess-Liste von PG ausgeben lassen. Wenn da irgendwo “inTransaction” statt “idle” steht - und woanders das aktuelle Statement - und sich nichts rührt, dann kannst du so ziemlich “wissen” dass da ein Client auf den anderen wartet … und dann musst du dir ueberlegen, ob diese situation gerade so sein kann / darf - und wenn nicht, woran es liegt usw.

Bei mir fehlte einst z.B. einfach eine proforma “ROLLBACK” auf die connection wenn sie in den Pool zurueckgestellt wurde.

pg admin client - ist das etwa psql? Wie kann ich dort die idle Transaktionen abfragen?

Nein.

Wie kann ich dort die idle Transaktionen abfragen?

Mache ein Select auf pg_stat_activity.

Andreas