getCurrentSession在web中进行hibernate
我正在用hibernate和jsp / servlet编写一个基于Web的应用程序。 我已经阅读了有关sessionFactory.getCurrentSession
和sessionFactory.openSession
方法的内容。 我知道它们之间的基本区别(使用getCurrentSession
您不必关闭连接,当您提交事务时,您的会话将自动关闭)。 根据我的理解,我们应该选择getCurrentSession
并通过session-per-request进行。
让我们考虑以下场景:
- 方法A调用
getCurrentSession
并获取当前会话 - 在方法A中,使用步骤1中的会话启动事务
- 方法A调用方法B,它也具有
getCurrentSession
并启动事务 - 方法B提交其事务
- 控制返回到方法A,它也提交事务
现在我的问题是
- 在步骤1和步骤3中找到的会话是否会是同一个会话?
- 如果问题1的答案是肯定的,那么它将如何处理第4步中的提交? 理想情况下,它应该在那里关闭会话,并且应该在步骤5中抛出exception。
- 如果问题1的答案为否,那么您如何处理这样的情况呢?
在步骤1和步骤3中找到的会话是否会是同一个会话?
它们应该是相同的,这在某种程度上是getCurrentSession()
的契约的一部分,只要工作单元尚未完成(即已提交或回滚事务getCurrentSession()
,您就会将Session
绑定到该线程。 使用Hibernate的Java Persistence就像这样(p.481):
调用全局共享
SessionFactory
上的getCurrentSession()
所有数据访问代码都可以访问同一个当前Session
– 如果它在同一个线程中调用的话。 提交(或回滚)Transaction
时,工作单元完成。 如果您提交或回滚事务,Hibernate还会刷新并关闭当前Session
及其持久性上下文。 这里的含义是在提交或回滚后调用getCurrentSession()
会产生一个新的Session
和一个新的持久化上下文。
您可能还想阅读Session#beginTransaction()
所说的javadoc。
如果问题1的答案是肯定的,那么它将如何处理步骤4中的提交。理想情况下,它应该在那里关闭会话并且应该在步骤5给出错误。
步骤4应该不是问题, Session
将被刷新, Transaction
将被提交并且Session
关闭。 但我希望第5步失败,因为TransactionException
(这是我的赌注)。 但是让我引用Transaction
的javadoc:
事务与会话关联,并且通常通过调用
Session.beginTransaction()
来实例化。 单个会话可能跨越多个事务,因为会话的概念(应用程序和数据存储区之间的对话)的粒度比事务的概念更粗略。 但是, 打算在任何时候最多有一个与特定会话相关联的未提交的事务 。
如上所述,我们正在讨论不应发生的事情(即设计问题)。
我对你的场景没有答案,因为我不会那样实现,因为它似乎在惹麻烦。 相反,我将在C中启动事务,其中C调用A和B,并让C发出提交。 骨骼:
public void c(...) { try { transaction.begin(); a(); b(); transaction.commit(); catch (Exception e) { transaction.rollback(); } }
所以这里, a()
和b()
不提交或回滚 – 他们如何知道整个业务任务已经完成? 他们可以抛出exception或者返回一个布尔值来告诉调用者某些东西是不对的并且需要回滚。
- 使用jpa和hibernate在orm.xml中定义命名查询
- 为什么hibernate将HibernateException更改为(未选中)RuntimeException
- Hibernate可以返回除List之外的结果对象的集合吗?
- 在Hibernate中保护实体免于级联删除
- 如何在struts2中使用@Valid注释触发validation?
- Hibernate + Java上的性能降低,但是当我使用相同的本机Oracle查询的TOAD时速度很快
- Hibernate / JPA + Derby – SELECT语句在GROUP BY,ORDER BY或选择列表中包含太多项
- 使用HQL进行内部联接
- Hibernate分页机制