# EJB - Transaction Attribute



## bronks (15. Feb 2006)

Hi!

Nehmen wir mal an es geht um Lagerhaltung, wie z.B. in SAP. Für dieses Beispiel gibt es keine Materialnummern, sondern nur ein Werk, dem mehrere Läger zugeordnet sind.

Im EJB-Modul habe ich folgendes eingerichtet:
EB: WerkstbestandEB
EB: LagerbestandEB
SB: BestandsFacadeSB (welche die beiden EBs anspricht) 

Die SB hat die beiden Methoden Zugang und Abgang, die man mit den Parametern Werk, Lager und Menge aufruft. Die Methoden erhöhen oder mindern den Lagerbestand und gleichzeitig den Werksbestand. Das sollte möglichst in einer Transaktion passieren.

d.h. Folgendes muß in den Methoden passieren.
1. Lagerbestand ermitteln
2. Lagerbestand erhöhen bzw. mindern
3. Werksbestand ermitteln
4. Werksbestand erhöhen bzw. mindern



A. Wenn ich bei allen Beans das TransactionAttribute auf RequiredNew setze, wird dann folgendes passieren????

Alle 4 Schritte laufen in einer eigenen Transaktion ab und wenn einer dieser Schritte in die Hose geht, dann wird die Transaktion abgebrochen und keiner der 4 Schritte wird ausgeführt. Das alles läuft automatisch ohne, daß ich im JavaCode etwas von einer Transaktion erwähnen muß. Richtig?


B. Wenn ich bei allen Beans das TransactionAttribute auf Required setze, wird dann folgendes passieren????

Zwei User erhöhen gleichzeitig den Bestand. d.h. der zweite User schickt seine Anforderung dann weg, während die erste Transaktion bereits läuft. Die SB sorgt dafür, daß beide Anforderung in einer gemeinsamen Transaktion behandelt werden. Richtig?

Bitte sagt mir ob ich das richtig interpretiert habe?

Danke

Bronks


----------



## Bleiglanz (16. Feb 2006)

hm, du musst schon nachdenken

wenn du ALLES auf RequiredNew setzt

dann läuft jede Methode in einer eigenen Transaktion (d.h. jede SessionBean-Methode, jede EJB-Methode,...)

du solltest

die SessionBean Methode auf RequiredNew, d.h. NUR am Einstiegspunkt wird eine Transaktion erzeugt

alle anderen auf Required (= auf die Transaktion aufspringen oder eine neue wenn keine da), oder auf Mandatory (d.h. auch im Notfall keine eigene aufmachen)

aber auch dein B) sollte korrekt funktionieren

wegen der Bestandserhöhung: nein, wenn zwei verschiedene User eine stateless-SessionBean Methode aufrufen, dann sind das zwei völlig getrennte Vorgänge


----------



## bronks (16. Feb 2006)

Bleiglanz hat gesagt.:
			
		

> hm, du musst schon nachdenken....


Vielen Dank. Jetzt ist das klar. 



			
				Bleiglanz hat gesagt.:
			
		

> ... aber auch dein B) sollte korrekt funktionieren
> wegen der Bestandserhöhung: nein, wenn zwei verschiedene User eine stateless-SessionBean Methode aufrufen, dann sind das zwei völlig getrennte Vorgänge


Wie sieht es dabei mit der Isolation aus? In o.g. Beispiel könnte es doch passieren, daß sich mehrere User bei einer Materialbuchung in die Quere komme, wenn ein User den Bestand erhöht und der andere User gleichzeitig mindert. Habe ich das richtig verstanden?

Wenn mehrere User gleichzeitig den Bestand erhöhen. Wird dann dann die Methode für Bestandserhöhung mehrere Male nacheinander durchlaufen und oder läuft diese parallel in mehreren Threads ab?


----------



## Bleiglanz (16. Feb 2006)

> Wie sieht es dabei mit der Isolation aus? In o.g. Beispiel könnte es doch passieren, daß sich mehrere User bei einer Materialbuchung in die Quere komme, wenn ein User den Bestand erhöht und der andere User gleichzeitig mindert. Habe ich das richtig verstanden?
> 
> Wenn mehrere User gleichzeitig den Bestand erhöhen. Wird dann dann die Methode für Bestandserhöhung mehrere Male nacheinander durchlaufen und oder läuft diese parallel in mehreren Threads ab?


da kommen jetzt die Isolationsstufe der Transaktion sowie einige Einstellungen im Appserver mit ins Spiel...

Grundsätzlich werden bei sowas die "zuständigen" Entitiy-EJBs für die Dauer der Transaktion gesperrt, auch wenn die einzelnen SessionBean-Methodenaufrufe parallel laufen (eine "hängt" dann)

also: 

mit findByPrimaryKey(17) holst du dir die Entity EJB für den Lagerbestand von X

dann erhöhst du den Lagerbestand

jetzt ist diese - "Entität Nummer 17" - innerhalb einer Transaktion in Gebrauch, und keine zweite kann hier mit einsteigen - d.h. der nächste User wartet bis die aktuelle Transaktion abgeschlossen ist

wenn du hier aber z.B. noch SQL direkt-Zugriffe mithineinbringst (über JDBC) dann kannst du ohne weiteres auch ein Kuddelmuddel erleben


----------



## bronks (16. Feb 2006)

Wow. Da steckt ja wirklich was dahinter! 



			
				Bleiglanz hat gesagt.:
			
		

> ... jetzt ist diese - "Entität Nummer 17" - innerhalb einer Transaktion in Gebrauch, und keine zweite kann hier mit einsteigen - d.h. der nächste User wartet bis die aktuelle Transaktion abgeschlossen ist ...


Weißt Du zufällig, ob diese Sperre alleine vom EJB-Container gehandled wird oder ob die Datensatzsperre direkt an die  Datenbank weitergegeben und der Satz von der Datenbank gesperrt wird?


----------



## Bleiglanz (16. Feb 2006)

Hmm, jeder Appserver hat da seine eigene Philosophie wie das ganze geregelt wird - oft auch in den diversen Hersteller-Deskriptoren einstellbar

schau mal in die Doku zu dem von dir verwendeten Container


----------



## bronks (17. Feb 2006)

Vielen Dank für die Aufklärung!


----------

