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
打开也意味着出现脏数据的可能性很高。