考虑一下我们计划开发一个非常大的企业应用程序。在这种情况下,应该是以下的最佳方式。
a)每个请求或每个用户的休眠会话数量?
b)申请中允许的交易数量?
c)连接池和休眠会话之间的关系?
d)Hibernate会话和JTA事务之间的关系?
e)Hibernate Session的数量会降低性能吗?如果是的话,原因是什么
感谢。
答案 0 :(得分:3)
a)按要求。它更具可伸缩性,允许物理JDBC连接池。
b)每个请求都是一个事务。此事务可能跨越不同的事务资源。在这种情况下,您最感兴趣的是数据库。对于每个数据库,将创建一个会话(假设在特定请求中访问数据库)。在请求周期结束时,将提交所有事务资源或不提交任何事务资源(两阶段提交)。在托管环境(应用程序服务器)中,事务资源被隐式登记到访问时在当前线程上发生的事务。用户(您的应用程序)可以与此事务交互以使用JTA api设置边界(请参阅UserTransaction)。
c)每个新创建的会话都将从连接池接收连接。
d)每个JTA事务每个数据库最多一个hibernate会话
是的,是的。我假设每个Session实际上都用于对DB做一些事情(参见上面的几点)。第一个原因是应用程序服务器和数据库服务器资源(CPU,内存,网络)的自然瓶颈。第二个原因与数据库锁(事务范围)和间接使用的版本锁定方案(会话范围)有关当在容器外部时,您必须使用独立的连接池/ JTA实现。一个例子是使用XaPool的JOTM。但是,Hibernate拥有与我所见的JOTM和C3P0之类的东西进行交互的API。
答案 1 :(得分:1)
a)对于单个数据库,您只能创建一个会话工厂,并且可以创建任意数量的会话。
b)始终需要数据库(或系统)事务边界。在数据库事务之外不会发生与数据库的通信(这似乎使许多习惯于自动提交模式的开发人员感到困惑)。始终使用明确的事务边界,即使对于只读操作也是如此。根据您的隔离级别和数据库功能,这可能不是必需的,但如果您始终明确划分事务,则没有任何缺点。但是,当您需要在EXTENDED持久化上下文中保留修改时,您必须在事务之外执行操作。
C)hibernate Session是Connection的包装器,允许您在不直接编写SQL的情况下保存POJO。
因此,hibernate Session是Connection的包装器。连接保存在连接池中。
当你调用SessionFactory.openSession时,hibernate首先从提供的连接池中获取一个Connection。然后它围绕该Connection创建一个Session并返回它。