# Datenkonsistenz und eigene Transaktion



## chrisbad (26. Nov 2012)

Hallo Gurus ;-)

ich habe mal wieder eine ganz allgemeine Frage zum Thema "Transaktionen" im Zusammenhang mit beispielsweise folgendem Szenario:

In meiner Webanwendung nutze ich ein Verzeichnis im Filesystem zum Speichern von hochgeladenen Bildern. Beim Speichervorgang kann der Benutzer noch zusätzliche Informationen zum Bild angeben.
Diese werden in einer Datenbank gespeichert.

Der Ablauf an sich ist klar und funktioniert. 
Aber was passiert, wenn der Benutzer/Server den Speichervorgang genau zwischen drin abbricht.
Z. B. durch Absturz oder Server-Neustart. Entweder der Datensatz wird gespeichert oder das Bild, aber eines von beiden fehlt. 

*Gibt es eine Möglichkeit den ganzen Ablauf in eine eigene Transaktion zu packen? Falls ja, wie?
*
Macht sich ein Programmierer über so was überhaupt Gedanken oder läuft das unter dem Motto "was kann ich dafür wenn mein Programm mit Gewalt unterbrochen wird"?

LG Chris


----------



## FArt (26. Nov 2012)

Darüber sollte sich der Programmierer Gedanken machen. Oder ein Architekt. Oder ein technischer Projektleiter. Kommt auf die Organisation drauf an.

Files und Transaktionen ist so eine Sache. Goolge mal danach. Es gibt APIs oder ResourceAdapter Implementierungen die das versuchen mehr oder weniger gut zu realisieren. Aber auch das Filesystem an sich kann das unterstützen.

Man könnte z.B. das speichern der Dateien asynchron über JMS auftrennen. Die Message mit der Datei wird in der gleichen Transaktion verschickt wie die Daten in die DB gespeichert werden.


----------



## bronks (26. Nov 2012)

chrisbad hat gesagt.:


> ... Entweder der Datensatz wird gespeichert oder das Bild, aber eines von beiden fehlt ...


EDIT: Wenn Du in der Transaktion erst den DatenbankInsert abschießt und danach die Datei speicherst, dann ist es egal was in der Transaktion schief geht und es wird nichts gespeichert. 



chrisbad hat gesagt.:


> ... *Gibt es eine Möglichkeit den ganzen Ablauf in eine eigene Transaktion zu packen? Falls ja, wie?
> *


Wenn Du es problemlos und konsistent haben willst, dann speichere auch die Bilder in der Datenbank.




chrisbad hat gesagt.:


> ... Macht sich ein Programmierer über so was überhaupt Gedanken oder läuft das unter dem Motto "was kann ich dafür wenn mein Programm mit Gewalt unterbrochen wird"? ...


Ein paar fehlende Bilder von leicht bekleideten Mädls sind verschmerzbar, aber wenn wegen einem unvollständigen Kommissionierbeleg eine Montagelinie stehen bleibt und je Minute € 6.000 den Bach runter gehen, dann wirst Du mit Deiner o.g.  Einstellung  nicht weit kommen.


----------



## chrisbad (26. Nov 2012)

bronks hat gesagt.:


> EDIT: Wenn Du in der Transaktion erst den DatenbankInsert abschießt und danach die Datei speicherst, dann ist es egal was in der Transaktion schief geht und es wird nichts gespeichert.
> 
> Wenn Du es problemlos und konsistent haben willst, dann speichere auch die Bilder in der Datenbank.



Hmmm, also ich bin im JEE6-Umfeld mit Glassfish unterwegs. JMS habe ich noch nicht so oft benutzt deswegen würde ich gerne darauf verzichten. Aktuell nutze ich die angesprochene Reihenfolge um das Problem halbwegs zu umgehen.

Den Gedanken die Bilder in die DB zu speichern hatte ich auch schon, allerdings reden wir hier von aktuell 4TB. Auch die Performanceeinbußen sind nicht zu verachten. Das Speichern auf dem Filesystem hat auch andere Vorteile ,-)



bronks hat gesagt.:


> Ein paar fehlende Bilder von leicht bekleideten Mädls sind verschmerzbar, aber wenn wegen einem unvollständigen Kommissionierbeleg eine Montagelinie stehen bleibt und je Minute € 6.000 den Bach runter gehen, dann wirst Du mit Deiner o.g.  Einstellung  nicht weit kommen.



Eben, sonst hätte ich wohl nicht gefragt ;(

Im Moment tüftel ich grad an einer Lösung mit Exceptions und einer Aufräumroutine im Fehlerfall.
Meint ihr ich komm damit zum Ziel? Hier fehlt mir einfach die Erfahrung.

LG Chris


----------



## FArt (26. Nov 2012)

chrisbad hat gesagt.:


> Im Moment tüftel ich grad an einer Lösung mit Exceptions und einer Aufräumroutine im Fehlerfall.
> Meint ihr ich komm damit zum Ziel? Hier fehlt mir einfach die Erfahrung.



Ich denke, damit wirst du nicht alle Fälle erwischen. Du wirst noch einen Konsistenzprüfer benötigen, der regelmäßig DB und Filesystem abgleicht, mit passenden Regeln auswertet und Ressourcen löscht.

Die JMS Variante hat den Vorteil, dass es eine echte Transaktion ist... und wäre ohne große Einarbeitung leicht umzusetzen.


----------



## bronks (26. Nov 2012)

chrisbad hat gesagt.:


> ... Aktuell nutze ich die angesprochene Reihenfolge um das Problem halbwegs zu umgehen ...


Du hast Dein Ziel erreicht. Wenn beides in einer Transaktion, in genau der Reihenfolge abläuft, dann hast Du entweder einen DB-Eintrag und eine neue Datei oder nichts von beiden, aber dafür eine Exception.

Den Gedanken die Bilder in die DB zu speichern hatte ich auch schon, allerdings reden wir hier von aktuell 4TB. Auch die Performanceeinbußen sind nicht zu verachten. Das Speichern auf dem Filesystem hat auch andere Vorteile ,-)





chrisbad hat gesagt.:


> ...Im Moment tüftel ich grad an einer Lösung mit Exceptions und einer Aufräumroutine im Fehlerfall. Meint ihr ich komm damit zum Ziel? Hier fehlt mir einfach die Erfahrung ...


Zum Aufräumen dürfte es nichts geben, aber der von FArt empfohlene Konsistenzprüfer wäre sicher nicht verkehrt.


----------



## bronks (26. Nov 2012)

FArt hat gesagt.:


> Ich denke, damit wirst du nicht alle Fälle erwischen ... Die JMS Variante hat den Vorteil, dass es eine echte Transaktion ist... und wäre ohne große Einarbeitung leicht umzusetzen.


Was meinst Du konkret, was schief gehen könnte bzw. welche Fälle er nicht erwischen würde? 
Rollt JMS automatisch Änderungen im Dateisystem zurück?


----------



## FArt (26. Nov 2012)

bronks hat gesagt.:


> Was meinst Du konkret, was schief gehen könnte bzw. welche Fälle er nicht erwischen würde?


Schwer zu sagen, ich kenne ja die konkrete Implementierung nicht. Aber Fehl(er)veralten ist in der einfallsreicher als der Entwickler. So ein Code wächst mit der Zeit, nämlich immer wenn ein Fall übersehen wurde...



bronks hat gesagt.:


> Rollt JMS automatisch Änderungen im Dateisystem zurück?


Nein. Das versenden der Nachricht läuft transaktional. Wird die Transaktion zurückgerollt, wird keine Nachricht geschickt und es landen keine Daten in der DB. Sonst passiert beides. Die Nachricht kann wieder transaktional verarbeitet werden, sprich der Empfänger schreibt die Datei. Tritt ein Fehler auf, wird die Message nicht verarbeitet (geht aber nicht verloren). Man kann die Verabeitung automatisch wiederholen lassen (um kurzfristige Fehler abzuhandeln) oder die Message auf Halde legen, die Fehlerursache beheben und danach die ausstehenden Messages verarbeiten lassen.

Vorteil: es ist garantiert, dass immer alle Aktionen ablaufen. 
Nachteil: es kann (im Fehlerfall) zu einem (evlt. deutlichen) zeitlichen Versatz kommen, bis die Daten konsistent sind (also die Datei existiert und die Daten in der DB sind). Aber in solchen Fehlerfällen hättest du mit deiner Lösung vermutlich auch Probleme. Auch im Gutfall sind die Daten nicht sofort konsistent, denn das File wird eben asynchron geschrieben.

Weniger aufwendig: einfach damit Leben, dass die Daten inkonsisten sein können und solche Daten löschen oder ignorieren. Das geht aber nur bei unkritischen Daten.


----------

