37 spring hibernate lazy-loading
虽然很多帖子都是关于Spring的OpenSession/EntityManagerInViewFilter的主题写的,但我找不到任何提到它的缺陷.根据我的理解,并假设使用@Transactional服务层的典型分层Web应用程序架构,过滤器的工作方式如下:
在步骤8和9中,仍然管理由线程的EntityManager加载的对象.因此,如果在这些步骤中触及了惰性关联,则将使用仍然打开的EntityManager从数据库加载它们.据我所知,每次这样的访问都要求数据库打开一个事务.Spring的事务管理将不会意识到这一点,因此我将其称为"隐式事务".
我看到2个问题:
一方面,这两个问题似乎足以拒绝使用此过滤器(性能损失,数据不一致).另一方面,这个解决方案非常方便,避免编写几行代码,问题1可能不那么引人注意,问题2可能是纯粹的偏执狂.
你怎么看?
谢谢!
正如您所说,OpenSessionInView过滤器在Web应用程序中非常方便.关于你提到的限制:
1)加载多个惰性关联将导致多个数据库事务,这可能会影响性能.
是的,转到数据库通常可能会导致性能问题.理想情况下,您希望在一次旅行中获取所需的所有数据.考虑使用Hibernate join-fetch.但是从DB中获取太多数据也会很慢.我使用的经验法则是每次绘制视图时都需要使用连接提取; 如果在大多数情况下不需要数据,我会在需要时让Hibernate懒惰地获取它 - threadlocal open session会帮助它.
2)根对象及其惰性关联被加载到不同的数据库事务中,因此数据可能是陈旧的(例如,由线程1加载的根,由线程2更新的根关联,由线程1加载的根关联).
想象一下在JDBC中编写这个应用程序 - 如果应用程序的一致性要求要求root和leaves都应该加载到同一个txn中,请使用join fetching.如果不是,通常就是这种情况,延迟提取不会导致任何一致性问题.
恕我直言,OpenSessionInView更重要的缺点是当你希望你的服务层在非web上下文中重用时.根据您的描述,您似乎没有这个问题.
| 归档时间: |
|
| 查看次数: |
17871 次 |
| 最近记录: |