# "stateless" vs "stateful" entwurf



## JanHH (29. Mrz 2012)

Hallo,

brauche mal Rat bzw. Meinungen..

es geht um ein Softwareprojekt (Webanwendung), wo der User diverse Dinge tut, Berechnungen ausgeführt werden, jeder User ein Set von mehreren hundert Variablen hat, die diverse Werte speichern, und bei jeder Aktion der Anwendung werden da Berechnungen durchgeführt, Überprüfungen, Werte verändert usw usf.

Zur Zeit ist es so dass alle Variablen in der Session gespeichert sind und nur am Anfang und Ende jeder Session ein Datenbankzugriff stattfindet. Beim Start der Session wird alles angelegt, wenn der User fertig ist mit dem Arbeitsprozess alles gespeichert. Zwischendurch findet alles nur in der Session statt. Vorteil: hohe Performance, Nachteil: Probleme bei Abbruch (Session-Timeout) und späterer Fortsetzung. Das ist sozusagen die "stateful" Variante.

Andere Möglichkeit: Alles persisten in der Datenbank halten, die Zugriffe (mehr oder weniger) stateless machen, bei einem Zugriff alle notwendigen Werte aus der Datenbank lesen (können schonmal einige Dutzend sein), die notwendingen Dinge tun, Veränderungen persistieren (und danach natürlich neue Web-Seite anzeigen).

Hat den Vorteil dass man bei Session-Timeout und Fortsetzung "nahtlos" weiter machen kann, wo bei der anderen Variante relativ umständlich und auch leicht fehleranfällig bei Timeout alles "zwischengespeichert" und bei Fortsetzung wieder gelesen wird.

Performance ist aber auch durchaus ein Aspekt der Anwendung. Aber das "normale" bei einer Webanwendung wäre eher die zweite Variante, oder?

Was meinen die Experten?

Als Technologie soll Seam 2 oder JEE6 mit JPA eingesetzt werden, aber gegen ein bisschen selbstgebautes SQL zwecks Performance-Tuning spricht nix.

Gruß+Danke
Jan


----------



## jwiesmann (29. Mrz 2012)

Hi,

also alles in der Session zu speichern halte ich für keine sehr gute idee .. da gehts schon bei 2 geöffneten Tabs mit den ersten Problemen los...
Das "normale" wäre definitiv die 2. Lösung 
Aber auch hier kann man, abhängig vom Anwendungsfall, sicherlich Lösungen finden, die irgendwie dazwischen liegen.
Wenn "nur" berechnet wird, würde ich mir einmal die erforderlichen Daten holen, eine ViewScope managedBean erstellen und darin mit den Zahlen jonglieren. Sollte dann mit den Werten weiter gearbeitet werden, zwischenspeichern und so weiter...

Also eigentlich gemäß dem Motto:
Keep it simple, stupid (KISS)

Sonst verrennst du dich in den Sessions schneller als dir lieb ist 
Gruß


----------



## JanHH (29. Mrz 2012)

Die ganze Anwendung ist reichlich komplex und in der Tat möchte ich einen Entwurf der so simpel und fehleranfällig ist wie möglich. Zur Zeit ist das ganze Handling bei Session-Timeout und Wiederaufnahme ziemlich fummelig und fehleranfällig. Ausserdem werden die Sessions ziemlich gross. Können schon mal 5-10 MB pro User werden. Bei einigen hundert Usern parallel wird da der Speicher knapp.

Hab nur Angst dass die Performance unter dem "Bottleneck Datenbank" leidet. Wenn z.B. pro Request auf 10-20 Variablen aus der Datenbank lesend und später noch auf 5 Stück schreibend zugegriffen wird.

Ausserdem die Datenbanktabelle mit den Variablen. Wenn man mal davon ausgeht, double als Datentyp zu benutzen. Sagen wir mal 300 Variablen pro User, 1000 User pro Projekt, 50 Projekte parallel. Wären dann 50.000 x 300 = 15.000.000 Zeilen in der Tabelle. Hm noch nicht WIRKLICH viel oder? Und Zugriff darauf, performancemässig? Wenn man z.B. Projekt-ID als Index nimmt und per User-ID und Variablenname nach einer Variablen sucht? Und das halt pro Request nicht bei einer sondern bei 20 Stück?

Idee=Variablen-Name (intern hat jede einen Namen) und Projekt-ID sowie User-ID als String als ID für die Variablen-Tabelle nehmen? Müsste das Auffinden doch erheblich beschleunigen..


----------



## Sym (30. Mrz 2012)

In die Session gehört so etwas in der Regel nicht. Wenn es Dir nur um Performanz geht und eine SQL-DB zu langsam ist (was natürlich nicht einfach nur gefühlt so sein sollte), könntet ihr vielleicht eine NoSQL-DB ausprobieren.

Sessiontimeouts bekommt man häufiger als einem lieb ist. Wenn der Benutzer ne halbe Stunde arbeitet und dann nen Kaffee holt ist die Akzeptanz wohl bei Null, wenn dann alles weg ist. Natürlich könntest Du die Daten im Sessiontimeout speichern, aber richtige Transparenz für den Benutzer schafft so etwas nicht.


----------



## JanHH (30. Mrz 2012)

Naja, zur Zeit IST es so und funktioniert auch. Aber ich denke über einen Neubau nach.

Was sagst Du denn zu der Idee, die Variablen mit einer ID oder Index-Spalte als String zu versehen, die die Variable EINDEUTIG identifiziert, zwecks schnellem Auffinden in der Datenbank?+

Und die Datenmenge? Eine Tabelle mit double-Werten und 100 Millionen Zeilen?


----------



## FArt (30. Mrz 2012)

Nimm den einfachsten Entwurf und schreibe einen POC. Triff dann eine Aussage darüber, ob du glaubst, die DB Zugriffe wären langsam oder ob sie wirklich langsam sind.
Schließlich gibt es ja auch noch ein Caching, sowohl in der Applikationsschicht, als auch auf der Datenbank.
Finde heraus, was im Zweifelsfall langsam ist und versuche diese Stellen passend zu optimieren, z.B. mit optimierten Abfragen und Index auf der DB.

Es geht nichts über ein klares, einfaches Design, wenn nötig mit Anpassungen an dedizierten Stellen.

Mit zustandsbehafteten Realisierungen hast du immer Probleme wenn es um Skalierung, Ausfallsicherheit usw. geht.


----------



## JanHH (31. Mrz 2012)

Tjo das denke ich ja auch.


----------

