Ich glaube, ich muss tiefer in das gehen, weil meine erste Antwort nicht absolut richtig war.
Ich werde auf JSR-220 verweisen. In Abschnitt 5.2 Abrufen einer EntityManager können Sie finden:
Ein Unternehmen Manager bei mehreren gleichzeitig ausgeführter Threads nicht mit anderen geteilt werden können. Auf Entitätsmanager kann nur in einer Single-Thread-Art zugegriffen werden.
Nun, das ist es. Sie können hier aufhören zu lesen und nie EntityManager in Singleton Bohnen verwenden, wenn nicht ordnungsgemäß synchronisiert.
Aber ich glaube, es gibt eine Verwirrung in der Spezifikation. Es gibt zwei verschiedene EntityManager Implementierungen. Die erste ist eine Provider-Implementierung (sprich Hibernate), die nicht zwingend threadsicher sein muss.
Auf der anderen Seite gibt es eine Container-Implementierung EntityManager. Das soll auch nicht wie oben beschrieben threadsicher sein. Die Implementierung des Containers fungiert jedoch als Proxy und delegiert alle Anrufe an den EntityManager des realen Providers.
So weiter in der Spezifikation in 5.9 Runtime Verträge zwischen dem Container und Persistenz Provider:
Für die Verwaltung einer Transaktion-scoped Persistenzkontext, wenn kein EntityManager ist bereits mit der zugehörigen JTA-Transaktion: Der Container erstellt einen neuen Entitätsmanager, indem er EntityManagerFactory.createEntityManager aufruft, wenn der erste Aufruf von ein Entitätsmanager mit PersistenceContextType.TRANSACTION innerhalb des Bereichs von a auftritt Geschäftsmethode, die in der Transaktion JTA ausgeführt wird.
Dies bedeutet wiederum, dass es eine andere EntityManager Instanz sein für jede Transaktion gestartet. Der Code, der eine EntityManager schafft sicher nach 5.3:
Methods der EntityManagerFactory Schnittstelle THREAD sind.
Aber was, wenn es ein EntityManager mit JTA Transaktion verbunden ist? Der Code, der einen EntityManager verknüpft, der mit der aktuellen JTA-Transaktion verknüpft ist, ist laut Spezifikation möglicherweise nicht sicher.
Aber ich kann nicht wirklich eine Anwendungsserverimplementierung denken, die korrekt mit EntityManager funktioniert, injiziert in statusfreie Beans und nicht korrekt innerhalb von Singletons.
Also meine Schlussfolgerungen sind:
- Wenn Sie die JSR-220 streng folgen wollen, dann EntityManager in Singletons verwenden nie den Zugang zu ihr, bis zu synchronisieren.
- Ich persönlich werde weiterhin EntityManager in Singleton verwenden, weil meine Anwendung Server-Implementierung perfekt damit arbeitet. Vielleicht möchten Sie Ihre Implementierung vorher überprüfen.
Beachten Sie, dass diese Antwort (obwohl akzeptiert wird) in der Tat nicht wahr ist, wie in einer anderen Antwort polbotinka erwähnt. Lesen Sie weiter, wenn Sie sich für "Thread-Sicherheit" mit 'Java EE EntityManager' interessieren. – Aquillo