在用hibernate3的过程中[color=red](先说明下,项目中没有用到Spring)[/color],出现过1次由于Oracle数据库无法分发连接造成项目不能正常运行的错误。但当时数据库的设置的可连接数是500,而且当时我用plus查询v$session时数量只有93个。之后查看日志文件及分析项目组各人当时手头的工作时,发现有可能是因为有人在拉报表时,造成数据库瞬间摒死。
由于平时数据库的连接一直很稳定,对于关闭session的问题也是凭以往的经验而行。但这次我们的疏忽造成了不良影响,因此,我自己总结了下对关闭session问题的想法和疑惑,有不对的地方和疑点,希望有心人多多指教,不盛感激!
我的理解,线程绑定是对Hibernate中线程进行有效管理的一种方式。由SessionFactory的多线程性,若想实现多线程共享一个Session实例是不行的。而解决办法可以为每个线程放一个Session的副本,并由每个线程自己维护这个Session,包括获得、使用、销毁。这样,可以实现Session的线程内共享。
在我看来,Session的线程内共享,是指,Session做为一种持久化的工具,可以用来将其中的各种对象与数据库之间进行交互。所以,直到未被销毁前,Session可以用来做各种各样的操作,如查询、保存、修改、删除等。但任何数据库都有最大连接限制,所以,当完成对数据库的操作后,必须断开与数据库的连接。然而,session只要不销毁,它与数据库的连接将一直存在,并随着用户操作的增加,连接数将不断增加。
因此,这里有个矛盾:既要实现session的共享,也即只用一个session来完成不同的操作,又要尽量使每个操作在完成后断开连接,也即关闭session。
对此,很多人在编程时可能都是这样做的:
[b]1[/b].每完成一个操作,都关闭当前线程中的Session,当再次需要时,由线程再次从SessionFactory中去获取。这样,可以保证所有的连接都能被释放,不会造成数据库连接次数的爆满。但这样做的话,线程内的Session一获得,一个操作后就销毁了,下一个操作还要到SessionFactory中去取,线程内共享Session还有什么意义?。
[b]2[/b].所有操作均不关闭Session,而是在每个请求结束后统一关闭。这样,很好地实现了线程内Session的共享。但这样的话,每个用户占用的连接数将大大增加,用户数量很多的话,很可能在某个时刻连接数没有得到及时释放,造成数据库连接爆了。打个比方,有个循环,内中有个未关闭Session的方法。如果想在这个循环内共享Session,在循环后再关闭这个Session,就很可能造成连接数在瞬间爆增(尤其在循环很大的情况下)。
有些人可能这样想:我在一个请求(jsp页面或servlet)的最后一个方法中关闭Session不就行了吗?然而,在当前页面中,这个方法可能是最后用到的,但到了另外一个页面中,说不定是第一个用到的。假如每个页面都在最后一个使用的方法上关闭Session,也许在XX个页面之后,所有的方法都关闭Session了。
由于平时数据库的连接一直很稳定,对于关闭session的问题也是凭以往的经验而行。但这次我们的疏忽造成了不良影响,因此,我自己总结了下对关闭session问题的想法和疑惑,有不对的地方和疑点,希望有心人多多指教,不盛感激!
我的理解,线程绑定是对Hibernate中线程进行有效管理的一种方式。由SessionFactory的多线程性,若想实现多线程共享一个Session实例是不行的。而解决办法可以为每个线程放一个Session的副本,并由每个线程自己维护这个Session,包括获得、使用、销毁。这样,可以实现Session的线程内共享。
在我看来,Session的线程内共享,是指,Session做为一种持久化的工具,可以用来将其中的各种对象与数据库之间进行交互。所以,直到未被销毁前,Session可以用来做各种各样的操作,如查询、保存、修改、删除等。但任何数据库都有最大连接限制,所以,当完成对数据库的操作后,必须断开与数据库的连接。然而,session只要不销毁,它与数据库的连接将一直存在,并随着用户操作的增加,连接数将不断增加。
因此,这里有个矛盾:既要实现session的共享,也即只用一个session来完成不同的操作,又要尽量使每个操作在完成后断开连接,也即关闭session。
对此,很多人在编程时可能都是这样做的:
[b]1[/b].每完成一个操作,都关闭当前线程中的Session,当再次需要时,由线程再次从SessionFactory中去获取。这样,可以保证所有的连接都能被释放,不会造成数据库连接次数的爆满。但这样做的话,线程内的Session一获得,一个操作后就销毁了,下一个操作还要到SessionFactory中去取,线程内共享Session还有什么意义?。
[b]2[/b].所有操作均不关闭Session,而是在每个请求结束后统一关闭。这样,很好地实现了线程内Session的共享。但这样的话,每个用户占用的连接数将大大增加,用户数量很多的话,很可能在某个时刻连接数没有得到及时释放,造成数据库连接爆了。打个比方,有个循环,内中有个未关闭Session的方法。如果想在这个循环内共享Session,在循环后再关闭这个Session,就很可能造成连接数在瞬间爆增(尤其在循环很大的情况下)。
有些人可能这样想:我在一个请求(jsp页面或servlet)的最后一个方法中关闭Session不就行了吗?然而,在当前页面中,这个方法可能是最后用到的,但到了另外一个页面中,说不定是第一个用到的。假如每个页面都在最后一个使用的方法上关闭Session,也许在XX个页面之后,所有的方法都关闭Session了。