|
|
1
45
因为在视图层中发送可能未初始化的代理(尤其是集合)并从视图层触发hibernate加载可能会从性能和理解的角度带来麻烦。 理解 : 使用osiv会“污染”视图层与数据访问层相关的关注点。
视图层不准备处理
性能 : osiv倾向于在地毯下拖拽适当的实体加载-您倾向于不会注意到您的集合或实体被惰性地初始化(可能是n+1)。更方便,更少控制。 更新: 看见 The OpenSessionInView antipattern 关于这个问题的更大的讨论。作者列举了三个要点:
|
|
2
39
要了解更多的描述,您可以阅读我的 Open Session In View Anti-Pattern 文章。否则,这里将总结为什么不应该在视图中使用open session。 视图中的打开会话获取数据的方法不正确。它不让业务层决定如何最好地获取视图层所需的所有关联,而是强制持久性上下文保持打开状态,以便视图层可以触发代理初始化。
乍一看,这看起来并不是一件可怕的事情,但是,一旦从数据库的角度来看,一系列的缺陷开始变得更加明显。
服务层打开和关闭数据库事务,但是之后,没有显式事务发生。因此,从ui呈现阶段发出的每个附加语句都以自动提交模式执行。自动提交给数据库服务器带来压力,因为每个语句都必须将事务日志刷新到磁盘,因此会在数据库端造成大量I/O通信。一个优化是标记
不再有关注点的分离,因为语句是由服务层和ui呈现过程生成的。编写集成测试 assert the number of statements being generated 需要遍历所有层(web、服务、dao),同时将应用程序部署到web容器上。即使在使用内存数据库(例如hsqldb)和轻量级web服务器(例如jetty)时,这些集成测试的执行速度也会比分层和后端集成测试使用数据库时慢,而前端集成测试则模拟服务。一层一层的。
ui层仅限于导航关联,这些关联反过来会触发n+1查询问题。尽管hibernate提供
最后但并非最不重要的是,数据库连接可以在整个ui呈现阶段保持(取决于连接释放模式),这会增加连接租用时间,并由于数据库连接池的拥塞而限制总体事务吞吐量。保持的连接越多,其他并发请求等待从池中获取连接的次数就越多。 因此,要么连接保持太长时间,要么为一个http请求获取/释放多个连接,从而对底层连接池施加压力并限制可伸缩性。 弹簧靴不幸的是, Open Session in View is enabled by default in Spring Boot .
所以,确保
这将禁用osiv,以便您可以
handle the
|
|
3
24
|
|
|
4
13
我不认为公开会议被认为是一种不好的做法;是什么给你这种印象? 视图中的打开会话是使用hibernate处理会话的简单方法。因为它很简单,有时也很简单。如果您需要对事务进行细粒度的控制,例如在请求中有多个事务,那么视图中的打开会话并不总是一个好方法。 正如其他人所指出的,osiv有一些折衷方案——你更容易遇到n+1问题,因为你不太可能意识到你正在启动什么样的事务。同时,这意味着您不需要更改服务层以适应视图中的细微更改。 |
|
|
5
5
如果您使用的是控制反转(ioc)容器,比如spring,那么您可能需要阅读
bean scoping
. 本质上,我告诉Spring让我冬眠
如前所述,您将不得不考虑n+1选择性能问题。之后,您始终可以配置hibernate实体,以便在性能有问题的地方执行紧急连接加载。 bean作用域解决方案不是特定于spring的。我知道picocontainer提供了相同的功能,我相信其他成熟的ioc容器也提供了类似的功能。 |
|
|
6
4
以我自己的经验来看,osiv还不错。 我唯一的安排是使用两种不同的交易: -第一个,在“服务层”中打开,在这里我有“业务逻辑” -第二个在视图呈现之前打开 |
|
|
7
3
我刚刚在博客上写了一篇关于何时在视图中使用开放会话的指导原则的文章。如果你感兴趣的话可以去看看。 http://heapdump.wordpress.com/2010/04/04/should-i-use-open-session-in-view/ |
|
|
8
1
我正在冬眠中。但我认为在一个hibernate会话中有多个事务是可能的。因此,事务边界不必与会话开始/停止事件相同。 osiv,imo,主要是有用的,因为我们可以避免在每次请求需要进行db访问时编写用于启动“持久性上下文”(也称为会话)的代码。 在您的服务层中,您可能需要调用具有不同事务需求的方法,例如“Required、New Required等”。这些方法唯一需要的是有人(即OSIV过滤器)已经启动了持久性上下文,因此它们只需要处理关于是-“嘿给我这个线程的休眠会话..我需要做些数据库的工作”。 |
|
|
9
1
这不会有太大帮助,但你可以在这里查看我的主题: * Hibernate Cache1 OutOfMemory with OpenSessionInView 我有一些内存不足的问题,因为opensessioninview和加载了很多实体,因为它们停留在hibernate缓存级别1中,并且没有被垃圾收集(我加载了很多实体,每页500个项目,但是所有实体都停留在缓存中) |