# Von Webanwendung in Dateien schreiben



## minnime (24. Mai 2012)

Hallöchen allerseits.

Ich bin zu dem Schluss gekommen dass für mein aktuelles Webprojekt (reines JSP, weiter nichts) eine Datenbank ziemlicher Overkill wäre. Ich will also für die Persistenz auf Dateien (hauptsächlich XML) zurückgreifen. Nun muss natürlich sichergestellt werden, dass immer nur eine Session der Webanwendung gleichzeitig in die Dateien schreibt. Nun ist die Frage wie ich das lösen soll. Soweit ich weiss wird jede Klasse nur einmal instanziert, als Singleton sozusagen. Würde es reichen wenn ich in einer Klasse den Dateizugriff erledige und alle Sessions der Webanwendung diese nutzen? Oder muss ich diese Klasse dann, auch wie eine Datenbankverbindung, über JNDI zur Verfügung stellen. Ich gehe davon aus dass jede Session in einem eigenen Thread abläuft, dann muss ich doch sicher Synchronisierungsmaßnahmen treffen?
Oder gibt es für solche Zwecke irgendwas vorgefertigtes aud der API das man nutzen kann?

Freue mich auf Tips und Hinweise.


----------



## nillehammer (24. Mai 2012)

In Deinem Text stecken einige falsche Aussagen drinnen. Ich glaube dass deren Verständnis aber elementar für erfolgreiche Webprogrammierung ist. Deswegen erstmal die Korrekturen.


> Nun muss natürlich sichergestellt werden, dass immer nur eine Session der Webanwendung gleichzeitig in die Dateien schreibt.


Wenn Du das machst, sperrst Du den Zugriff auf die Datei für alle anderen Nutzer für die Lebensdauer der Session. Ob eine Webanwendung, die mehrere Minuten lang nur von einem Nutzer benutzt werden kann, sinnvoll ist, naja. Du musst also einen feingranulareren Sperrmechanismus haben oder jeder Nutzer arbeitet mit seiner eigenen Datei.


> Soweit ich weiss wird jede Klasse nur einmal instanziert, als Singleton sozusagen.


Blödsinn, Klassen kannst Du so oft instanzieren wie Du willst (sofern sie einen erreichbaren Konstruktor haben natürlich). Und bei den Container-Managed Klassen (bspw. Servlets) darfst Du dich auf nichts verlassen. Kann sein, dass der Container ein Singleton draus macht, kann sein, dass er für jeden Request eines neu instanziert, kann sein, dass er einen Pool hat... Wenn Du statt instanziert, *geladen* meinst, damit kann man arbeiten und ein Singleton implementieren, wenn man will.


> Würde es reichen wenn ich in einer Klasse den Dateizugriff erledige und alle Sessions der Webanwendung diese nutzen? Oder muss ich diese Klasse dann, auch wie eine Datenbankverbindung, über JNDI zur Verfügung stellen.


Kann man beides machen. JNDI entkoppelt Deine Anwendung etwas von der Implementierung, aber gehen tut beides.


> Ich gehe davon aus dass jede Session in einem eigenen Thread abläuft,


Falsch. *Requests* werden i.d.R in eigenen Threads abgearbeitet eine Session "läuft" in dem Sinne garnicht. Sie ist einfach ein Objekt mit einer definierten Lebenszeit, in welchem Objekte gespeichert werden können.

Und nun zur Frage: Ich denke, wenn Du mit einer Singleton-Implementierung eines XML-Persistenz-Service startest, der auf ein zentrales Objekt synchronisiert, bist Du erstmal am besten bedient. Das ist leicht umzusetzen und zu durchschauen. Wenn du merkst, dass konkurriernde Zugriffe zu langsam sind, kannst Du das ja aufweichen. Bspw. konkurrierende Lesezugriffe sind zugelassen, werden nur von Schreibzugriffen geblockt, Schreibzugriffe blocken alles etc. Dafür gibt es ja diese schöne neue Lock-API in Java.

P.S. Ach ja, und sone nette kleine Embedded Datenbank à la HSQLDB oder Derby ist garnicht so Overkill. Musst halt die JDBC-Api können. Dafür sparst Du Dir aber die ganzen Gedanken, die Du Dir hier machen musstest.


----------



## minnime (24. Mai 2012)

nillehammer hat gesagt.:


> Wenn Du das machst, sperrst Du den Zugriff auf die Datei für alle anderen Nutzer für die Lebensdauer der Session. Ob eine Webanwendung, die mehrere Minuten lang nur von einem Nutzer benutzt werden kann, sinnvoll ist, naja. Du musst also einen feingranulareren Sperrmechanismus haben oder jeder Nutzer arbeitet mit seiner eigenen Datei.


Ich meinte damit den Schreibvorgang als solches, die Datei soll eben nicht mehrere Minuten geblockt werden, deswegen ja die Idee mit der zentralen Klasse die die Schreibanforderungen der Servlets und auch die Leseanforderungen abarbeitet. Die Schreibvorgänge treten nicht so häufig auf, etwa einmal die Minute pro Session und das Lesen etwa genauso oft.



nillehammer hat gesagt.:


> Blödsinn, Klassen kannst Du so oft instanzieren wie Du willst (sofern sie einen erreichbaren Konstruktor haben natürlich). Und bei den Container-Managed Klassen (bspw. Servlets) darfst Du dich auf nichts verlassen. Kann sein, dass der Container ein Singleton draus macht, kann sein, dass er für jeden Request eines neu instanziert, kann sein, dass er einen Pool hat... Wenn Du statt instanziert, *geladen* meinst, damit kann man arbeiten und ein Singleton implementieren, wenn man will.


Ich meinte die Variante mit den Container-Managed Klassen und deren Verwaltung in einem Pool. Jetzt wo ich es lese, dämmert mir auch wieder dass das wohl nur für Servlets u.ä. gilt



nillehammer hat gesagt.:


> Und nun zur Frage: Ich denke, wenn Du mit einer Singleton-Implementierung eines XML-Persistenz-Service startest, der auf ein zentrales Objekt synchronisiert, bist Du erstmal am besten bedient. Das ist leicht umzusetzen und zu durchschauen. Wenn du merkst, dass konkurriernde Zugriffe zu langsam sind, kannst Du das ja aufweichen. Bspw. konkurrierende Lesezugriffe sind zugelassen, werden nur von Schreibzugriffen geblockt, Schreibzugriffe blocken alles etc. Dafür gibt es ja diese schöne neue Lock-API in Java.
> 
> P.S. Ach ja, und sone nette kleine Embedded Datenbank à la HSQLDB oder Derby ist garnicht so Overkill. Musst halt die JDBC-Api können. Dafür sparst Du Dir aber die ganzen Gedanken, die Du Dir hier machen musstest.


Mir ist da ein Konstrukt mit einer Art Auftragswarteschlange vorgeschwebt. D.h. alle Request-Threads stellen ihre Leseanfragen und Schreibaufträge an eine zentrale Stelle und zumidest die Schreibaufträge müssen synchronisiert werden.
Naja, vielleicht ist das Ganze doch nicht so einfach, dann steige ich halt lieber auf die Datenbank um.
So eine Datenbank ist für viele Webanwendungen eigentlich zuviel des Guten, hab ich gehört und in diesem Fall ist das halt so. Ich hab die Wahl zwischen einer Datenbank mit ca. 15 Tabellen mit Vererbungsbeziehungen und was weiss ich nicht allem, wird ein recht umständliches Datenmodell. Oder ich nehme drei Dateien, zwei mal XML aus denen fast nur gelesen wird und einer csv in die fast nur geschrieben wird. Die Belastung durch die Datenbank auf technischer Seite interessiert mich nicht, die ist eh schon da und läuft, ich wollte es nur etwas vereinfachen.


----------



## nillehammer (25. Mai 2012)

minnime hat gesagt.:
			
		

> wird ein recht umständliches Datenmodell. Oder ich nehme drei Dateien, zwei mal XML aus denen fast nur gelesen wird und einer csv in die fast nur geschrieben wird. Die Belastung durch die Datenbank auf technischer Seite interessiert mich nicht, die ist eh schon da und läuft, ich wollte es nur etwas vereinfachen.


Das ist ein legitimer Gedankengang. Gerade bei stark baumartigen Datenstrukturen finde ich XML auch viel besser als Datenbanktabellen. Ich denke nur, dass es bei XML in Files am Ende so viele Probleme zu lösen gibt, dass sie die Vereinfachung der Datenstruktur überwiegen.

Du hattest ja im ersten Post nach APIs gefragt. Da fallen mir als Stichpunkte _Objektdatenbanken_ und _Dokument/XML-Datenbanken_ ein. Bei ersteren werden direkt die Java-Objekte gespeichert. DB4O ist da wohl die bekannteste. Bei zweiteren wird genau das gespeichert, über das Du hier nachdenkst, XML-Dokumente. Ich habe mir beides mal angeschaut, bin dann aber wieder zur relationalen Datenbank gekommen. Grund war eigentlich nur meine Faulheit, mich in eine neue API einzuarbeiten. Relationale DBs sind eben meist schon da, man selbst (und andere Entwickler auch) kennt die API usw.


----------



## minnime (25. Mai 2012)

Die Idee mit den anderen Datenbanktypen ist gut, geht aber nicht weil ich am Server keine andere Software installieren darf und auch nicht will. Entweder ich nehme die vorhandene Oracle-Datenbank oder Dateien. Die Alternative ist, die Datenbank als Dateisystem zu missbrauchen, was ich aber unschön finde. Oder es wird eine hybride Lösung indem die hierarchischen Daten, die den Inhalt der Anwendung beschreiben als XML in der Datenbank ablege, was ja direkt möglich ist und die von der Anwendung kommenden Daten werden klassisch relational gespeichert.

Auf jeden Fall danke ich danke danke für die Antworten.


----------

