数据库连接未关闭的问题?

时间:2023-01-26 23:43:14
使用struts框架,服务器使用tomcat,部分画面需要的数据是统计数据,当数据达到100W行以上的时候,点查询,画面生成需要好几分钟,用户觉的慢,会关闭当前窗口,但是服务器端无法立即感受到,画面的进程会继续执行,数据库连接没释放,反复多次,数据连接被用完,系统出错,希望大家交流下,看有没有好的办法处理

10 个解决方案

#1


在查询的时候加个控制计数器,超过多少行就不查了,跳出。

#2


100w条分据,一次生成?输出还是生成文件?

#3


先retrieve一部分数据响应用户(这样用户就不会觉得没有响应关闭当前窗口了),需要的时候再处理后面的数据。
不知道这样合不合要求?

#4


先等等,姑且不论这样的全件查找是否必要,你上面说画面生成要好几分钟,客户关浏览器什么的,但是在生成画面的时候,也就是JSP这些表示层的时候,数据库连接应该已经关闭了呀(具体的构架可能不一样,我就简单武断地认为是在Action.execute()方法结束前),到了JSP显示的时候,已经和数据库连接没有关系了吧,你不会把数据库连接写道JSP上了吧? 

如果还在“Action”这一侧,可否考虑先wait起来,等其他线程结束了,notify一下阿,再继续;还有更简单的方法,一旦察觉数据库连接池“出超”严重,把用户引入到一个其他页面,上述“服务器忙,请稍候”,以缓解压力?

#5


一个HTTP请求只要被servlet接受就算是客户端关闭窗口,HTTP响应还是要继续被servlet产生的,这没什么办法,我个人不太赞成对service thread进行操作,所以你的问题最好就是通过减小server端的处理量来缩短请求/响应的时间。
如果一定要这么大的处理量,需求一定要这么变态的话,我建议你可以加一个进度条和取消按钮让用户知道处理的过程,我曾经坐过一个情况类似于你的要求。
我给他提交到一个弹出的modal dialog(要用iframe或者frameset否则modal dialog不能再提交),在那里面处理这个超长的请求,然后server端的servlet打开数据库连接,把statment放到session里,执行statement每处理5%就flush response一点javascript来到客户端的这个弹出窗口,弹出窗口运行这段小的js来删除掉旧信息防止叶面太大,同时并更新进度条,并把parent窗口更新数据。然后弹出叶面还有一个cancel按钮,你当然不能cancel处理请求的service thread, 不过你可以提交cancel操作去从session拿到st执行statement.cancel()来中断数据库操作。
注意,这需要对js很熟悉,如果js封装不好,会很头疼,而且说实话把statement放到session不是一个规范的编程方法,过程也很复杂。

#6


调整你的业务来实现吧.

a. 浏览. 100w没有意义, 分页或做业务汇总实现
b. 接口或文件. 可分成两步, 请求和下载

数据库不管执行成功与否都必须要释放, 否则任何调整都是徒劳的
conn = ...
try{
  ...
} finally {
  conn.close();
}

#7


xue xi

#8


维护一个冲突窗口。
逻辑如下:
1.客户请求 --〉  
2.服务端 提交一个执行的查询到冲突窗口,如果冲突窗口已经有同样的类型在处理。取消掉它,
  并将当前处理加入冲突窗口,执行之。

元素:  
控制线程。
冲突窗口。
工作线程。

实现过程
对于每一个访问的客户(靠session来判别)。
如果需要进行一个数据库处理,则将该对象交给控制线程(一般放入控制线程的队列里),

控制线程到冲突窗口(一般用hashtable实现)根据一定的规则(如某一个客户的某一种类型的请求)察看是否已有处理在进行。如果有,则取消该处理。
将当前交易插入冲突窗口,并通知相关工作线程进行处理。

修改成本:相对于旧程序,
只需要加入一个控制线程,和一个冲突窗口,并对已有的线程增加点是否取消的判断和移除数据的操作外,基本没有大的影响。

工作线程 接受到通知后 到冲突窗口取数据,执行之,如果执行成功则做成功处理,如果执行失败
则做失败处理,之后到冲突窗口移除该数据(或通知控制线程移除该数据),如果被取消,则什么也不做。



#9


这个地方是需要100W一次查询的,因为这里等于是要出每月的统计报表,所以SQL语句慢,基本上是没有办法的,我是希望能有啥简单的方法,得到用户已经关闭了窗口,这样一来就很糟糕了.

#10


优化数据库,提高数据库服务器的性能,100W条数据应该很快可以响应的

#1


在查询的时候加个控制计数器,超过多少行就不查了,跳出。

#2


100w条分据,一次生成?输出还是生成文件?

#3


先retrieve一部分数据响应用户(这样用户就不会觉得没有响应关闭当前窗口了),需要的时候再处理后面的数据。
不知道这样合不合要求?

#4


先等等,姑且不论这样的全件查找是否必要,你上面说画面生成要好几分钟,客户关浏览器什么的,但是在生成画面的时候,也就是JSP这些表示层的时候,数据库连接应该已经关闭了呀(具体的构架可能不一样,我就简单武断地认为是在Action.execute()方法结束前),到了JSP显示的时候,已经和数据库连接没有关系了吧,你不会把数据库连接写道JSP上了吧? 

如果还在“Action”这一侧,可否考虑先wait起来,等其他线程结束了,notify一下阿,再继续;还有更简单的方法,一旦察觉数据库连接池“出超”严重,把用户引入到一个其他页面,上述“服务器忙,请稍候”,以缓解压力?

#5


一个HTTP请求只要被servlet接受就算是客户端关闭窗口,HTTP响应还是要继续被servlet产生的,这没什么办法,我个人不太赞成对service thread进行操作,所以你的问题最好就是通过减小server端的处理量来缩短请求/响应的时间。
如果一定要这么大的处理量,需求一定要这么变态的话,我建议你可以加一个进度条和取消按钮让用户知道处理的过程,我曾经坐过一个情况类似于你的要求。
我给他提交到一个弹出的modal dialog(要用iframe或者frameset否则modal dialog不能再提交),在那里面处理这个超长的请求,然后server端的servlet打开数据库连接,把statment放到session里,执行statement每处理5%就flush response一点javascript来到客户端的这个弹出窗口,弹出窗口运行这段小的js来删除掉旧信息防止叶面太大,同时并更新进度条,并把parent窗口更新数据。然后弹出叶面还有一个cancel按钮,你当然不能cancel处理请求的service thread, 不过你可以提交cancel操作去从session拿到st执行statement.cancel()来中断数据库操作。
注意,这需要对js很熟悉,如果js封装不好,会很头疼,而且说实话把statement放到session不是一个规范的编程方法,过程也很复杂。

#6


调整你的业务来实现吧.

a. 浏览. 100w没有意义, 分页或做业务汇总实现
b. 接口或文件. 可分成两步, 请求和下载

数据库不管执行成功与否都必须要释放, 否则任何调整都是徒劳的
conn = ...
try{
  ...
} finally {
  conn.close();
}

#7


xue xi

#8


维护一个冲突窗口。
逻辑如下:
1.客户请求 --〉  
2.服务端 提交一个执行的查询到冲突窗口,如果冲突窗口已经有同样的类型在处理。取消掉它,
  并将当前处理加入冲突窗口,执行之。

元素:  
控制线程。
冲突窗口。
工作线程。

实现过程
对于每一个访问的客户(靠session来判别)。
如果需要进行一个数据库处理,则将该对象交给控制线程(一般放入控制线程的队列里),

控制线程到冲突窗口(一般用hashtable实现)根据一定的规则(如某一个客户的某一种类型的请求)察看是否已有处理在进行。如果有,则取消该处理。
将当前交易插入冲突窗口,并通知相关工作线程进行处理。

修改成本:相对于旧程序,
只需要加入一个控制线程,和一个冲突窗口,并对已有的线程增加点是否取消的判断和移除数据的操作外,基本没有大的影响。

工作线程 接受到通知后 到冲突窗口取数据,执行之,如果执行成功则做成功处理,如果执行失败
则做失败处理,之后到冲突窗口移除该数据(或通知控制线程移除该数据),如果被取消,则什么也不做。



#9


这个地方是需要100W一次查询的,因为这里等于是要出每月的统计报表,所以SQL语句慢,基本上是没有办法的,我是希望能有啥简单的方法,得到用户已经关闭了窗口,这样一来就很糟糕了.

#10


优化数据库,提高数据库服务器的性能,100W条数据应该很快可以响应的