说来惭愧,这个问题早在2005年就在javaeye上被讨论得很彻底了,有2个精华帖:
http://www.javaeye.com/topic/15057,http://www.javaeye.com/topic/17501
Spring有开发出OpenSessionInViewFilter这样的东西来帮助我们在事物方法的session关闭,能在view层继续使用同一个线程的session。
使用方法,可以参考:http://www.cnblogs.com/children/archive/2010/05/01/1725419.html
问题是明显:如果页面load延迟过大,比如网络传输延迟(拨号用户过多等),会导致session一直开着,数据库的连接而得不到及时释放,对于并发量大的internet系统,直接的后果是数据库资源的耗尽。
Robbin与众人讨论的结果是:对于并发量大的网络系统,请慎用OpenSessionInViewFilter。如果不用OpenSessionInViewFilter,那么怎么解决呢?
Robbin说用Hibernate.initialize()。
用Hibernate.initialize(),等于说,你在后台强制去初始化级联的对象集合,然后页面取得的就是一个完整的po对象了,不需要open Session了。
也就是说,你并没有利用到lazy-loading,只是你config文件里配置了lazy-loading=true,实际上你在使用时已经强制把它变成false了。
关于Hibernate.initialize()的使用,可以参考:http://blog.youkuaiyun.com/haydenwang8287/article/details/1798094
其实,OpenSessionInView真的是Spring+struts+Hibernate框架一个绕不过去的坑,最好的办法就是换一个framework。
比如用seam框架就从根源上解决了这个问题。seam是hibernate之父一手打造的,想必他肯定有考虑过这个问题。