Frage

wird mit dem ‚synchronisierten‘ Keyword auf Methoden in einer Java DAO gehen Probleme zu verursachen, wenn sie von einer Web-Anwendung verwendet?

Ich frage, weil ich eine Multi-Threaded-Stand-alone-Anwendung, die die Methoden von synchronisiert muss Ressourcenkonflikt zu vermeiden, wie hier zu sehen.

java.util.concurrent.ExecutionException: javax.persistence.PersistenceException: org.hibernate.HibernateException: Found shared references to a collection: com.replaced.orm.jpa.Entity.stuffCollection

Was mich betrifft, ist, dass, wenn eine große Zahl von Menschen versuchen, die Anwendung verwenden, die die synchronisierten Methoden blockiert und die gesamte Anwendung verlangsamen.

Ich bin mit einem Frühling-injizierten JPA Entity Manager Fabrik, die ein Unternehmen Manager an den DAO zur Verfügung stellt. Ich konnte die DAO Schicht technisch entfernen und haben die Klassen direkt an das Unternehmen Manager Fabrik nennen, aber ich genieße die Trennung der DAO bietet.

nicht passieren um verbunden Entität ORM-Objekte zwischen Threads

Ich sollte auch beachten Sie, dass ich sehr vorsichtig bin zu sein. Ich spekuliere, dass der Ressourcenkonflikt Fehler kommt zustande, wenn die DAO zugreifen. Ich denke, dass mehrere Threads zur gleichen Zeit gehen und versuchen, aus der Datenbank in nicht-atomaren Möglichkeiten bestehen bleiben oder lesen.

In diesem Fall wird unter Verwendung eines DAO wird mehr Schaden zuzufügen dann helfen?


Ein großes Stück von Informationen, die ich aus der Frage bleibt, ist, dass die DAO kein Singleton ist. Wenn ich klar genug gedacht hatte, um dieses Detail umfassen würde ich wahrscheinlich nicht die Frage in erster Linie gefragt habe.

Wenn ich richtig verstehe, erstellt Frühling eine neue Instanz der DAO-Klasse für jede Klasse, die es verwendet. So ist die Trägereinheit Manager sollten auf jeden Thread eindeutig sein. Nicht teilt das Unternehmen Manager, als Rob H beantwortet, die wichtige Sache hier.

Aber jetzt verstehe ich nicht, warum ich Fehler, wenn ich synchronisiert entfernen.


Nach dieser fädeln , erstellt die @PersistenceContext Annotation eine Gewinde- Safe SharedEntityManager. So sollten Sie in der Lage sein, einen Singleton DAO zu erstellen.

War es hilfreich?

Lösung

Sie sagen, Sie nicht Entitätsobjekten über Threads miteinander teilen. Das ist gut. Aber Sie sollten auch sicherstellen, dass Sie sind nicht teilen EntityManager Objekte (oder Sitzung Objekte in Hibernate) über Threads entweder. Frameworks wie Spring verwaltet dies automatisch durch die Sitzung in einem Thread-lokalen Variablen speichern. Wenn Sie Ihre eigene Codierung DAOs ohne die Hilfe eines Rahmens, müssen Sie sich nehmen Vorsichtsmaßnahmen zu teilen, sie zu vermeiden.

Wenn Sie dies tun, sollte es keinen Grund geben DAO Methoden zu synchronisieren, da keiner der Gesprächszustand wird über Threads gemeinsam genutzt werden. Dies ist entscheidend für eine sehr gleichzeitige Web-Anwendung. Die Alternative ist, dass nur ein Thread der Lage sein wird, die DAO auf einmal zugreifen, sie alle teilen die gleiche DAO-Instanz übernehmen. Nicht gut auf allen für den Durchsatz.

Andere Tipps

Wenn es braucht für Thread-Sicherheit synchronisiert werden, dann lassen sie dort. Die Sperrung ist erforderlich, ohnehin in diesem Fall. Wenn die Blockierung nicht für den Web-Anwendungsfall erforderlich ist, können Sie entweder:

  • lassen Sie es wie es ist, da die Leistung schlagen, wenn es keinen Streit auf die Sperre vernachlässigbar ist, und unbedeutend, wenn berücksichtigt die Kosten, die Datenbank des Schlagens.
  • Redesign es so, dass Sie ein hinzufügen Synchronisationsschicht für die Standalone Anwendungsfall der schützt die darunter liegende unsynchronisierten DAO.

Persönlich würde ich es lassen wie es ist und das Profil zu sehen, wenn Sie ein Refactoring benötigen. Bis dahin tun Sie einfach vorzeitige Optimierung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top