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