11.1.4. 常见问题

决不要使用反模式session-per-user-session或者 session-per-application(当然,这个规定几乎没有例外)。请注意, 下述一些问题可能也会出现在我们推荐的模式中,在你作出某个设计决定之前,请务必理解该模式的应用前提。

  • Session 对象是非线程安全的。如果一个Session 实例允许共享的话,那些支持并发运行的东东,例如HTTP request,session beans,或者是 Swing workers,将会导致出现资源争用(race condition)。如果在HttpSession中有 Hibernate 的Session的话(稍后讨论),你应该考虑同步访问你的Http session。 否则,只要用户足够快的点击浏览器的“刷新”,就会导致两个并发运行线程使用同一个 Session

  • 一个由Hibernate抛出的异常意味着你必须立即回滚数据库事务,并立即关闭Session (稍后会展开讨论)。如果你的Session绑定到一个应用程序上,你必 须停止该应用程序。回滚数据库事务并不会把你的业务对象退回到事务启动时候的状态。这 意味着数据库状态和业务对象状态不同步。通常情况下,这不是什么问题,因为异常是不可 恢复的,你必须在回滚之后重新开始执行。

  • Session 缓存了处于持久化状态的每个对象(Hibernate会监视和检查脏数据)。 这意味着,如果你让Session打开很长一段时间,或是仅仅载入了过多的数据, Session占用的内存会一直增长,直到抛出OutOfMemoryException异常。这个 问题的一个解决方法是调用clear()evict()来管理 Session的缓存,但是如果你需要大批量数据操作的话,最好考虑 使用存储过程。在第 13 章 批量处理(Batch processing)中有一些解决方案。在用户会话期间一直保持 Session打开也意味着出现脏数据的可能性很高。