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

时间:2010-06-23 13:26:09

标签: java hibernate session orm

我最近采用了我们项目的数据库/ hibernate方面,并且在理解我们关于托管会话使用的设计基础方面遇到了很大麻烦。

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

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

我觉得我们必须以错误的方式使用Hibernate,拥有一个永久打开的会话似乎不对。当单独的线程使用util类时,它也会导致问题,因此共享会话。另一方面,我找不到用不同设计实现上述好处(特别是第一个)的方法。任何人都可以对此有所了解吗?

由于

詹姆斯

3 个答案:

答案 0 :(得分:2)

  

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

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

  • Session不是线程安全的。
  • 如果要保持对象状态和数据库同步,则应在Hibernate异常后回滚事务并关闭 Session
  • 如果将Session打开太久,{{1}}会无限增长。

你真的需要阅读整个Chapter 11. Transactions and Concurrency

  

另一方面,我找不到采用不同设计实现上述优势的方法(特别是第一种)。

使用OSIV(Open Session In View)模式或明确加载每个流所需的内容。如果您想从全局缓存中受益,请使用二级缓存。

答案 1 :(得分:1)

保持会话开放一段时间是可以的(虽然这不应该是永恒的:-)会话应该识别工作单元 - 一组连贯的查询/更新逻辑上永远在一起。你能在你的应用中识别出这样的单位 - 例如客户请求或对话?如果是,请为每个会话创建一个单独的会话。

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

答案 2 :(得分:0)

这是一种反模式。

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

SessionFactory是静态/每个应用程序,而不是Session。工厂应该在需要时建立一个会话。在hibernate上阅读sessions and transactions个文档。