在quarkus样本中,我看到ApplicationScoped bean用作EntityManager注入的服务类。
据我所知(JEE)EntityManager不是线程安全的,ApplicationScoped bean也不是。如果将实体管理器注入ApplicationScoped bean,则看起来我们在请求之间共享同一实体管理器。
如果ApplicationScoped bean是线程安全的,那么我们只能同时接受一个请求。
我不明白为什么我们在EntityManager注入中使用ApplicationScoped而不是RequestScoped Bean。
答案 0 :(得分:2)
当您can see时,Quarkus与使用JPA构造的其他项目一样,在幕后做了很多工作,以确保您作为最终用户接收到的上下文引用的行为安全正确。 / p>
(免责声明:我不是Quarkus专家,但是这种特殊的模式将EntityManager
操作委派给不同的基础EntityManager
代表,具体取决于事务状态,与同步相关的问题和其他问题在整个应用程序中服务器)。
注入所谓的“容器管理的” EntityManager
的行为在人们直觉上期望他们的行为上是相当棘手的。作为最终用户在这一领域要当心,这是正确的:实际上,从EntityManagerFactory#createEntityManager()
收到的EntityManager
并不是线程安全的。但这不是注入到此类插槽中的内容。例如,以这种方式注入的EntityManager
会做其他令人兴奋的事情,例如自动参与JTA事务,而这些事务本质上是特定于线程的,因此必须进行一定程度的线程安全性,依此类推。等等。显然,与简单注入由应用程序管理的EntityManager
相比,这里发生的事情更多。
要点是:EntityManager
bean收到的ApplicationScoped
引用是线程安全的。