Warum sind EJBs sicher und Servlets nicht?

7

Nach meinem Verständnis erstellt ein Servlet-Container begrenzte Instanzen von Servlets und mehrere Threads jeder Servlet-Instanz und verwendet diese Threads und Instanzen erneut.

Da es mehrere Instanzen eines Threads gibt, sind diese nicht "Thread-sicher" (obwohl ich verstehe, dass das Codieren mit Thread-Sicherheit nicht schwierig ist).

EJBs-Container dagegen erstellen keine Threads von EJB, sondern nur EJB-Objekte (mit Pool). Da es keine Mehrfach-Threads einer EJB-Instanz gibt, ist die Thread-Sicherheit keine Frage.

Meine Frage: Warum haben Sie ein anderes Verhalten? Ist es keine gute Idee, EJBs als Servlets (Threads unsicher) zu betreiben?

Ich bin mir sicher, dass ich etwas vermisse und diesen fehlenden Teil verstehen will.

    
Sandeep Jindal 26.06.2012, 22:01
quelle

3 Antworten

8

Wahrscheinlich, weil sie nicht mit den gleichen Zielen entworfen wurden.

Die Servlet-API ist eine einfache API, die dem HTTP-Protokoll sehr nahe kommt und auf der Sie Anwendungen oder Frameworks erstellen können. Da das HTTP-Protokoll völlig zustandslos ist, war es wahrscheinlich sinnvoll, auch eine statusfreie API zu erstellen. Mehrere Frameworks, die auf der Servlet-API (z. B. Stripes) basieren, verwenden eine Instanz von Aktion pro Anforderung, die nicht gleichzeitig verwendet wird.

EJBs sind ein viel komplexeres Framework auf hoher Ebene, das darauf ausgelegt ist, transaktionale Geschäftslogik so einfach wie möglich zu implementieren. Es ist schwerer und hat Stateful-Komponenten. Diese müssen natürlich threadsicher sein. Ich denke, es war also natürlich, auch statusfreie Bohnen fadensicher zu machen.

Es sollte beachtet werden, dass Spring-Beans beispielsweise standardmäßig Singles sind und daher denselben Regeln wie Servlets folgen müssen. So sind mehrere Designs möglich, um mehr oder weniger die gleiche Funktionalität zu bieten.

Threads haben nichts mit einer Leistungsoptimierung zu tun. Wenn Sie 3 Anfragen gleichzeitig bearbeiten müssen, benötigen Sie 3 Threads, unabhängig davon, ob die Anfrage an ein Servlet oder an ein EJB geht.

    
JB Nizet 26.06.2012, 22:13
quelle
8

Die kürzeste Antwort auf Ihre Frage ist natürlich ist es eine gute Idee, um es möglich, EJBs wie Servlets zu arbeiten und in EJB 3.1 wir eine Komponente hinzugefügt, die genau das tun können, dass: @Singleton

Eine @Singleton -Bohne kann wie ein Servlet multi-threaded sein, entweder:

  • Verwendung von @ConcurrencyManagement(BEAN)
  • Verwenden @ConcurrencyManagement(CONTAINER) zusammen mit @Lock(READ) auf Verfahren, bei denen die Parallelität und @Lock(WRITE) auf Verfahren gewünscht wird, die nicht sicher sind, fädeln.

Eine andere Sache, die Servlets seit Jahren hatten, die EJBs nie hatten, war <load-on-startup> , was einem Servlet erlaubt, eifrig zu laden und am Anwendungsstart zu arbeiten.

Um das Servlet <load-on-start> anzupassen, haben wir die Annotation @Startup hinzugefügt, die zu jedem @Singleton EJB hinzugefügt werden kann und bewirkt, dass sie beim Start der Anwendung gestartet wird. Bei diesen Beans wird die Methode @PostConstruct aufgerufen, wenn die Anwendung gestartet wird, und ihre @PreDestroy wird aufgerufen, wenn die Anwendung beendet wird.

Anstatt eine Nummer zu verwenden ( <load-on-startup>1</load-on-startup> ), den Auftrag zu diktieren, in der mit @Startup Start kommentierten Bohnen, Sie Bohnen mit @DependsOn und geben Sie eine Liste von Bohnen, die vor der kommentierten Bohne beginnen müssen mit Anmerkungen versehen können.

Und ein weit weniger bekannt und verstanden Aspekt haben wir EJB 3.1 in auszurichten Servlets und EJBs war natürlich EJBs zu ermöglichen, innerhalb von .war Dateien verpackt werden - das ist nicht der weniger bekannte Teil - und wenn wir das gemacht haben dass wir die Definition von java:comp/env im Stillen so geändert haben, dass sie dem Servlet-Ansatz entspricht.

Vor EJB 3.1 gab es keine Möglichkeit, zwei EJBs einen java:comp/env -Namespace zu teilen ( java:comp/env ist bean-scoped in der EJB-Spezifikation). Servlets hatten im Gegensatz dazu nie die Möglichkeit, dass einzelne Servlets ihren eigenen privaten java:comp/env -Namespace hatten ( java:comp/env ist in der Servlet-Spezifikation modulspezifisch). So in EJB 3.1 ein EJB, die in einem Krieg gepackt ist das gleiche Modul-scoped java:comp/env Namensraum wie alle anderen Servlets und EJBs in der Webapp haben, was ein ziemlich großer Unterschied zum bohnen scoped ist java:comp/env Namespace, EJBs wenn sie außerhalb eines Krieges in eine OHR verpackt werden. Wir diskutierten darüber seit Wochen.

Nettes kleines bisschen Bier-Zeit trivial, um deine Freunde zu quizieren.

    
David Blevins 27.06.2012 01:30
quelle
3

Ihre beste Antwort ist direkt aus dem Javadoc für das javax.servlet.SingleThreadedModel Schnittstelle:

  

Veraltet. Ab Java-Servlet-API 2.4 ohne direkten Ersatz.

     

public interface SingleThreadModel

     

Stellt sicher, dass Servlets jeweils nur eine Anfrage bearbeiten. Diese Schnittstelle hat keine Methoden.

     

Wenn ein Servlet diese Schnittstelle implementiert, sind Sie garantiert , dass keine zwei Threads gleichzeitig in der Servlet-Methode des Servlets ausgeführt werden. Der Servlet-Container kann diese Garantie übernehmen, indem er den Zugriff auf eine einzige Instanz des Servlets synchronisiert oder indem er einen Pool von Servlet-Instanzen verwaltet und jede neue Anfrage an ein freies Servlet sendet.

     

Beachten Sie, dass SingleThreadModel nicht alle Thread-Sicherheitsprobleme löst . Auf Sitzungsattribute und statische Variablen kann beispielsweise immer noch mit mehreren Anforderungen auf mehreren Threads gleichzeitig zugegriffen werden, auch wenn SingleThreadModel-Servlets verwendet werden. Es wird empfohlen, dass ein Entwickler andere Methoden zum Beheben dieser Probleme einbaut, anstatt diese Schnittstelle zu implementieren, z. B. die Verwendung einer Instanzvariablen zu vermeiden oder den Block des Codes, der auf diese Ressourcen zugreift, zu synchronisieren. Diese Schnittstelle ist in der Servlet-API Version 2.4 veraltet.

    
Toddius Zho 26.06.2012 22:39
quelle