getCurrentSession在web中进行hibernate

时间:2010-09-26 13:28:10

标签: java hibernate orm

我正在使用hibernate和jsp / servlet编写基于Web的应用程序。我已阅读有关sessionFactory.getCurrentSessionsessionFactory.openSession方法的内容。我知道它们之间的基本区别(使用getCurrentSession您不必关闭连接,当您提交事务时,您的会话将自动关闭)。根据我的理解,我们应该选择getCurrentSession并通过每个请求进行会话。

让我们考虑以下情况:

  1. 方法A调用getCurrentSession并获得当前会话
  2. 在方法A中,使用步骤1的会话开始交易
  3. 方法A调用方法B,方法B也有getCurrentSession并开始交易
  4. 方法B提交其交易
  5. 控制权返回方法A,并且还提交交易
  6. 现在我的问题是

    1. 在步骤1和步骤3中找到的会话是否会是同一会话?
    2. 如果问题1的答案是肯定的,那么它将如何处理第4步中的提交?理想情况下,它应该关闭会话,并在步骤5中抛出异常。
    3. 如果问题1的答案为否,那么您如何处理这种情况?

2 个答案:

答案 0 :(得分:7)

  

在步骤1和步骤3中找到的会话是否会是同一会话?

它们应该是相同的,这在某种程度上是getCurrentSession()合同的一部分,只要工作单元尚未完成,你就会得到Session的约束(即事务已提交或回滚)。 Java Persistence with Hibernate 就像这样(p.481):

  

在全局共享上调用getCurrentSession()的所有数据访问代码   SessionFactory可以访问相同的当前Session - 如果它在。{   相同的线程。提交(或回滚)Transaction时,工作单元完成。如果提交或回滚事务,Hibernate还会刷新并关闭当前Session及其持久性上下文。这里的含义是在提交或回滚后调用getCurrentSession()会产生一个新的Session和一个新的持久化上下文。

您可能还想阅读Session#beginTransaction()的javadoc所说的内容。

  

如果问题1的答案是肯定的,那么它将如何处理步骤4中的提交。理想情况下,它应该关闭那里的会话,并且应该在步骤5给出错误。

第4步应该不是问题,Session将被刷新,Transaction将被提交并且Session已关闭。但我希望第5步失败TransactionException(这是我的赌注)。但是,让我引用Transaction的javadoc:

  

事务与会话关联,并且通常通过调用Session.beginTransaction()来实例化。单个会话可能跨越多个事务,因为会话的概念(应用程序和数据存储之间的对话)的粒度比事务的概念更粗略。但是,打算在任何时候最多有一个与特定会话相关联的未提交的交易

如上所述,我们正在讨论不应发生的事情(即设计问题)。

答案 1 :(得分:6)

我对你的场景没有答案,因为我不会那样实现,因为它似乎在惹麻烦。相反,我将在C中启动事务,其中C调用A和B,并让C发出提交。骨架:

public void c(...) {
    try {
       transaction.begin();
       a();
       b();
       transaction.commit();
    catch (Exception e) {
       transaction.rollback();
    }
}

所以在这里,a()b()不提交或回滚 - 他们如何知道整个业务任务已经完成?他们可以抛出一个异常或者返回一个布尔值来告诉调用者有什么不对,需要回滚。