代码之家  ›  专栏  ›  技术社区  ›  James

我应该使用静态的非静态会话吗?

  •  1
  • James  · 技术社区  · 14 年前

    我最近接手了我们项目的数据库/休眠方面的工作,在理解关于托管会话使用的一些设计基础时遇到了严重的问题。

    我们有一个包含静态会话的Util类,该会话只初始化一次。系统中的每个DAO都使用静态方法getBoundSession()来检索会话。应用程序全天候运行。这是一种常见的设计吗?

    其中一个非常有用的好处是,域对象上的惰性属性/集合可以在整个业务逻辑层中使用,因为会话始终是开放的。另一个好处是检索到的对象将在会话中保持缓存。

    我觉得我们一定是用了错误的方式使用了Hibernate,似乎没有一个永久打开的会话是正确的。另外,当单独的线程使用Util类时,它也会导致问题,从而共享会话。另一方面,我找不到一种方法来通过不同的设计实现上述好处(尤其是第一个)。有人能解释一下吗?

    谢谢

    詹姆斯

    3 回复  |  直到 14 年前
        1
  •  2
  •   Pascal Thivent    14 年前

    我们有一个包含静态会话的Util类,该会话只初始化一次。系统中的每个DAO都使用静态方法getBoundSession()来检索会话。应用程序全天候运行。这是一种常见的设计吗?

    不是。最常见的模式 多用户 客户端/服务器应用程序是 每个请求的会话 和A 每个应用程序的会话 多用户应用程序中的方法不仅是反模式,而且是完全错误的:

    • Session 不是线程安全的。
    • 您应该回滚一个事务并 关闭 这个 会话 如果要保持对象状态和数据库同步,则在休眠异常之后。
    • 这个 会话 如果开得太久,就会无限期地生长。

    你真的需要通读 Chapter 11. Transactions and Concurrency .

    另一方面,我找不到一种方法来通过不同的设计实现上述好处(尤其是第一个好处)。

    要么使用OSIV(在视图中打开会话)模式,要么明确地加载每个流所需的内容。如果您想从全局缓存中获益,请使用第二级缓存。

        2
  •  1
  •   Péter Török    14 年前

    延长会话的开放时间是可以的(尽管这不应该是永恒的):-)会话应该标识 工作单位 -逻辑上属于一起的一组连贯的查询/更新。你能在你的应用中识别出这样的单位吗?比如客户请求或对话?如果是这样,请为每个会话创建一个单独的会话。

    您还应该为每个线程使用单独的会话(通常工作单元由单个线程处理)。实现这一点的一个简单方法是使用 thread local storage .

        3
  •  0
  •   Bozho    14 年前

    这是一种反模式。

    如果对所有请求使用一个会话。然后考虑100个客户机(100个请求/线程)几乎同时运行。您从会话中分离了一些内容,但随后另一个用户重新加载了相同的内容。您将需要同步,这将影响性能。您将拥有完全随机的行为,这将是调试的噩梦。

    这个 SessionFactory 是静态的/每个应用程序,而不是 Session . 工厂应在需要时建立会话。读 sessions and transactions 文档处于休眠状态。