问题
EntityManager
is not thread-safe by definition.
Servlets specs says that in non-distributed environment and without implementing SingleThreadModel
, there is only one servlet instance per definition.
Therefore, in Java EE when you inject an EntityManager
through the @PersistenceContext
into Servlet's field - it's not thread safe:
public class MyServlet extends HttpServlet {
// Not thread-safe, should be using EMF instead.
@PersistenceContext
private EntityManager em;
}
Is this correct to say that even though the default scope of Spring beans is singleton, the
EntityManager
is thread-safe as the Spring usesThreadLocal
to bind its transaction andEntityManager
to it?Is the above Servlets example still valid in Spring? Is it still not thread-safe?
Does the
ThreadLocal
approach works only for Spring managed beans and plain servlet is not one of those?As far as I remember, it's the container responsibility to inject the
EntityManager
. In Glassfish Java EE implementation, it was the application server who discovers the@PersistenceContext
as injection point.
How does it look like in Spring? Is the Spring Framework responsible for discovering those annotations or it's responsibility of the JPA implementor?
回答1:
Question 2, 3, and 4 -- Spring does not pay attention to any class that is not a Spring Bean. Therefor Spring does not pay attention to you MyServlet
class.
Therefore the answer for
- 2) is no
- 3) only Spring managed Beans
- 4) it is Springs responsibility, because Spring is the Container
For Question 1). It works this way, so the usage of an Spring Injected Entity Manager is effective thread save.
来源:https://stackoverflow.com/questions/10380539/persistencecontext-entitymanager-thread-safety-in-spring-and-java-ee