Synchronized in JavaEE

R

reNur

Gast
Hallo,

eine etwas blöde Frage - aber ich bin mir irgendwie nicht sicher:

Die Benutzung von "manuellen" Locks usw. ist ja innerhalb EJB verboten, ich darf also beispielsweise kein "synchronized" in einem Stateless EJB verwenden.

Ist es aber erlaubt, auf ganz normalen Java-Objekten, die von EJBs aufgerufen werden, Methoden als synchronized zu deklarieren?
 

FArt

Top Contributor
Nachdem jeder Call seine eigene Instanz eines SLSB erhält, besteht dort kein Bedarf für Synchronisation. Ausnahme ist ein Singleton Bean, aber da kann man über den Container oder das Bean synchronisieren lassen (EJB 3.1 Spec - 4.8.5 Bean Concurrency).
 
R

reNur

Gast
Hallo,

ich glaub ich verstehe das noch nicht ganz.
Angenommen, ich habe 2 SLSBs, die auf eine Datenbanktabelle zugreifen - z.B. Hinzufügen eines Artikels in eine Tabelle "Bestellung". Jeder Artikel hat eine Nummer (z.B. Position 1, 2, 3,....), die pro Bestellung einmalig ist.

Egal wie ich auf die Datenbank zugreife - die Vergabe dieser Unique-ID erfolgt ja letztendlich im Datenbankmanagementsystem. Sollten nun 2 SLSB quasi gleichzeitig einen Artikel hinzufügen wollen, so erfolgt ja wohl die Synchronisation auf DB-Seite, sprich irgend ein Lock wird angelegt.

So, und angenommen ich habe die Daten einer Bestellung nicht in einer DB, sondern also "normales" Java-Objekt (Bestellung.java oder wie auch immer). Und dieses Objekt hat die Methode "Artikel hinzufügen", und in dieser Methode wird die Unique-ID festgelegt. Darf ich dann die Methode dieser Klasse als synchronized deklarieren (z.B. public synchronized int artikelHinzufuegen) und dann diese Klasse in einer JavaEE Umgebung benutzen?
 

FArt

Top Contributor
Hallo,

So, und angenommen ich habe die Daten einer Bestellung nicht in einer DB, sondern also "normales" Java-Objekt (Bestellung.java oder wie auch immer). Und dieses Objekt hat die Methode "Artikel hinzufügen", und in dieser Methode wird die Unique-ID festgelegt. Darf ich dann die Methode dieser Klasse als synchronized deklarieren (z.B. public synchronized int artikelHinzufuegen) und dann diese Klasse in einer JavaEE Umgebung benutzen?

Wie "normal" ist denn dein Objekt? Wie stellst du sicher, dass alle Beans diese Objektinstanz zu sehen bekommen und somit konsistente IDs ziehen?
Den Service für die IDs sollte man über eine SLSB als Singleton realsieren.
 
R

reNur

Gast
Hallo,

Das Szenario, bei dem ich mir diese Gedanken gemacht habe, war folgendes:
Ich arbeite eigentlich an einer ganz anderen Baustelle. Für ein paar Tests habe ich mir Features anlegen müssen, die erst später richtig implementiert werden. Dazu gehört eben auch eine Art "Bestellungs"objekt.

Dieses Object hat eine Unique ID, die später sicherlich in einer Datenbank etc. verwaltet wird. Für meine Zwecke habe ich mir ein Singleton EJB gebaut, in dem eine Methode "erzeuge neue Bestellung" implementiert ist, die eine neue Instanz des Objekts "Bestellung" anlegt und auch die ID vergibt.
Analog dazu gibt es eine Methode "getBestellung(id)" in dem Singleton Bean.

Jedes SLSB, das mit einer ID die getBestellung-Methode aufruft, erhält also die richtige Instanz, da hier im Singleton synchronisiert wird.

Dann habe ich mir überlegt, was wohl passieren würde, wenn ich die Methoden der Klasse "Bestellung" nicht über das Singleton laufen lassen (also z.B. im SingletonBean "addArtikel( Bestellung, Artikel ), sondern direkt auf dem Object eine Methode "synchronized addArtikel(Artikel)" hinzufüge.
 

FArt

Top Contributor
Nun, jedes SLSB hat eine eigene Instanz. Auf dieser Instanz wird nicht konkurrierend zugegriffen, somit ist synchronized unnötig. Die Frage wäre in dem Fall immer noch: wer hält deinen Zähler und in welcher Form?
Wenn du an ein (static) Field im SLSB denkst, dann lautet die Antwort: das ist laut Spec verboten, weil nicht sichergestellt ist, dass das funktioniert.
 
R

reNur

Gast
Der Zähler liegt im Singleton Bean...

mal als Pseudocode:

Java:
@Singleton
public class SingletonClass...

private List<Bestellungen> liste;
private int zaehler;

public void addBestellung( Bestellung b )
{
int id = zaehler + 1;
b.setId(id)
}

public Bestellung getBestellung( int id )
{
return liste.get( id )
}


Nun, und wenn die Klasse Bestellung nun eine Method addArtikel( String artikel ) hätte - könnte man diese synchronisieren?
 
R

reNur

Gast
Aber was, wenn nicht?

Also wenn - nur so als Beispiel - Artikel messagebasiert hinzugefügt werden. Mehrere MDBs hören auf eine "füge Artikel zu Bestellung mit ID x hinzu" Nachricht. Trifft diese ein, so holen sie sich eine Instanz der Bestellung über die Singleton Bean. Zu der entsprechenden ID wird - da Singleton - ja immer die selbe Instanz der Bestellung zurückgeliefert. Es kann also sein, dass mehrere MessageDriven Beans eine Bestellungs-Instanz bearbeiten und mit "addArtikel" einen Artikel hinzufügen wollen.
 

FArt

Top Contributor
Das wäre fehlerhaftes Design in einem EE Umfeld.

Du denkst einfach zu "kleinkariert", also mit den Gedanken eines Java-Entwicklers, nicht eines Enterprise-Entwicklers. Wie du schon sagtest, sind das natürlich normalerweise Entitäten auf der DB und somit über die Transaktion gekapselt. Wenn du so etwas zur Laufzeit machen möchtest, müsstest du das in einem Singleton Bean ("Service") tun, also nicht den Artikel herausgeben.

Das Problem in der Enterpriseumgebung ist, dass du mit einfachen Javamitteln gar nicht sinnvoll synchronisieren kannst. Es kann, bedingt durch Konfiguration und Infrastruktur, passieren, dass zwei Consumer zwar die selbe Entität, aber verschiedene Instanzen davon refernzieren. Somit haben diese auch verschiedene Monitore beim synchronisieren.
 
R

reNur

Gast
Hmm ok ich verstehe schon dass man das aus einer anderen Sichtweise betrachten muss.
Bei Entitäten, die in Datenbanken verwaltet werden, ist mir das auch sonnenklar. Wenn ich mir aus dem DB-Object eine Java-Instanz generiere, steht diese ja praktisch in keiner Verbindung zum DB-Object und muss erst wieder persistent gemacht werden, damit die Änderungen in dem Objekt überhaupt vorgenommen werden.
Aber technisch gesehen erhält jeder Aufruf zu einer getBestellung-Methode doch genau ein Objekt dass in irgendeiner Speicheradresse liegt... wobei ich merke schon, da muss ich mich noch einlesen.

Eine andere Frage, die mir gerade gekommen ist:
Angenommen, ich habe eine Singleton-Bean, die alle Bestellungen verwaltet. Clients (also andere EJBs) können selbstständig neue Artikel-Objekte erstellen (die wiederum Attribute wie z.B. Name, Anzahl etc. enthalten).
Dann werden diese Artikel an die Bestellung übergeben - also z.B. durch Aufruf einer addArtikelPosition( BestellungsID, ArtikelObject )-Methode der Singleton Bean. Im Singleton wird dann die ID des Artikels gesetzt etc. Ist das ein 'sauberer' Ansatz.

P.S.: Das sind alles nur Fragen bzw. Beispiele, die mich im Zusammenhang mit JEE beschäftigen - ich versuche also nicht, eine Shop-Applikation oder so zu entwickeln ;)
 

FArt

Top Contributor
Aber technisch gesehen erhält jeder Aufruf zu einer getBestellung-Methode doch genau ein Objekt dass in irgendeiner Speicheradresse liegt... wobei ich merke schon, da muss ich mich noch einlesen.
Nein, genau das ist ja der Haken. Die Spezifiakation sichert dir lediglich zu, dass du ein Objekt der Klasse A mit dem passenden Inhalt siehst. Das kann auch eine Kopie sein. Bei Calls auf eine Remoteinterface war das früher immer eine Kopie (marshalling/unmarshalling beim Call). Heutzutage optimieren Applikationsserver den Call in der Regel in einer VM, aber wie gesagt: das kann der Container machen wie er lustig ist.

Angenommen, ich habe eine Singleton-Bean, die alle Bestellungen verwaltet. Clients (also andere EJBs) können selbstständig neue Artikel-Objekte erstellen (die wiederum Attribute wie z.B. Name, Anzahl etc. enthalten).
Dann werden diese Artikel an die Bestellung übergeben - also z.B. durch Aufruf einer addArtikelPosition( BestellungsID, ArtikelObject )-Methode der Singleton Bean. Im Singleton wird dann die ID des Artikels gesetzt etc. Ist das ein 'sauberer' Ansatz.
Das ist ein unpraktisches Beispiel, aber egal. Nennen wir das Singleton-Bean "Bestellservice" (das muss kein Singleton Bean sein, das wäre lediglich ein Implementierungsdetail) dann wäre das ein konsistenter Weg. Über Aufgaben (somit Methoden) des Services müsste man sich in deinem Fall wieder ein wenig streiten, aber im Prinzip wäre das so richtig.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
V wo synchronized anwenden? Allgemeines EE 3
ARadauer static synchronized in JSP Allgemeines EE 5
K Synchronized bei zentralem Datenzugriff bei WebApps? Allgemeines EE 4
T Stand von JavaEE und AppServern Allgemeines EE 10
L JavaEE Webanwendung - Datenbank-Verbindung aufbauen Allgemeines EE 18
G Unit Test einer JavaEE Anwendung schlägt fehl. JNDI Name nicht gefunden. Allgemeines EE 3
G JavaEE Anwendung Testen Allgemeines EE 0
R Wiederverwendbarkeit in JavaEE Anwendung Allgemeines EE 2
P JavaEE 7 Maven Eclipse Allgemeines EE 0
OnDemand GUI in einer JavaEE Anwendung Allgemeines EE 6
P JAvaEE und JNDI Allgemeines EE 0
P JavaEE- Projekt in Netbeans Allgemeines EE 0
T JBossESB Welche JavaEE Verison? Allgemeines EE 0
J Netbeans + JavaEE. NullPointerException Allgemeines EE 3
S Verteilte Anwendung mit JavaEE Allgemeines EE 3
J Security JavaEE 6 Allgemeines EE 7
H Die ersten Schritte mit JavaEE Allgemeines EE 2
M JavaEE Anwendung weitergeben Allgemeines EE 24
Chris81T JavaEE Backend < > HTML Frontend ( Frameworks ) Allgemeines EE 10
G web.xml javaee tag Allgemeines EE 2
G Aussagen zu JavaEE Allgemeines EE 9
D maven für javaEE projekt Allgemeines EE 20
T javaee.jar und rt.jar Allgemeines EE 2
G Netbeans und JavaEE - Projects Allgemeines EE 4
G Von Java SE nach JavaEE umsteigen Allgemeines EE 31

Ähnliche Java Themen

Neue Themen


Oben