我们目前正在开发一个使用 JPA 作为我们的数据访问层的 J2EE 网络应用程序。我们目前正在考虑几种不同的策略来在我们的应用程序中使用缓存。
- >
为每个请求创建一个
EntityManager
- > 在请求范围内获取缓存,但在请求结束时丢失缓存
- > 使回滚整个请求的任何更改变得容易
- >
为每个 Http Session 创建一个
EntityManager
- > 在 session 范围内获取缓存
- > 使事务变得更加复杂,必须为每个请求创建一个新事务,然后能够回滚每个请求的更改
我在 Hibernate 文档中看到了这两种策略。我的问题是哪个使用更广泛,如果我们在每个 session 中执行 EntityManager
,我们是否会通过在不同的请求线程中使用相同的 EntityManager
来遇到同步问题?
最佳答案
更广泛使用的方法是为每个请求创建一个 EntityManager
。但是,这应该对您隐藏。您应该使用一些依赖项注入(inject)机制 (spring/CDI/EJB),该机制将在放置 @PersistenceContext
的位置注入(inject)正确的 EntityManager
。
如果您对在您的 bean 是某种单例(一个无状态 bean/一个作用域单例的 spring bean)的常见情况下如何实现这一点感兴趣 - 容器实际上在目标对象中注入(inject)了一个代理。每次咨询代理时,它都会获取 current EntityManager
实例,该实例(至少在 spring 的情况下)绑定(bind)到 ThreadLocal
(在这种情况下=请求)
更新:如果您想在自己开发的框架中实现此功能,请使用 cglib/javassist/JDK 代理并将其注入(inject)到 @PersistenceContext
所在的位置。请求 = 线程。在每个需要数据访问的请求上,创建一个新的 EntityManager
并将其存储在 ThreadLocal
中。记得最后清理它,因为 servlet 容器会重用线程。从代理中,您可以获得当前的 ThreadLocal
值。
但如果您对项目的了解不深,那么我建议您转向更稳定的东西,例如 spring、cdi 或 guice。
关于java - JPA Web 应用程序管理策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4418979/