2011-07-24 30 views
1

我正在使用Java Servlets的网站上工作,我的研究表明,最好每个用户保持一个数据库连接(而不是每次都只有一个连接坐在后台或连接到数据库)交易需要作出)。但是,我不知道如何完成这个任务。什么我目前做的是在我的数据访问对象类我有一个如何在Java Servlet应用程序上为每个用户创建一个数据库连接?

private static Connection conn; 

,我有一个HTTPSessionListener - 上sessionCreated事件我连接到数据库使用这种静态“conn将”变量,并在sessionDestroyed事件我断开在 “参数conn” 变量:

...在我的 “MySessionListener” ......

public void sessionCreated(HttpSessionEvent sessionEvent) { 
    System.out.println("Session created!"); 
    DAO.connect(); 

} 

public void sessionDestroyed(HttpSessionEvent sessionEvent) 
{ 
    System.out.println("Session destroyed"); 
    String user = (String) sessionEvent.getSession().getAttribute("userid"); 
    if (user != null) DAO.signUserOut(user); 
    DAO.disconnect(); 
} 

现在有了这个问题是:

  1. 恐怕这种方式本质上会降低到只有一个人人共享的连接(而不是每个用户的连接),只是我不时断开连接,如果没有用户。正确?
  2. 如果多个用户在线并且一个用户关闭了他们的会话,他们将关闭每个人的连接,直到其他人开始会话并为每个人创建一个新的连接,对不对?我无法对此进行很好的测试,因为我在笔记本电脑上使用3台浏览器在本地进行测试,但即使关闭了有我的网站的浏览器,该会话也不会立即死亡,而且我也不确定究竟发生了什么。我所知道的是,有时候我会得到一个异常,说“连接关闭后不允许交易”。

回答

5

通常这是使用连接池实现的。您可以将其配置为具有特定数量的可用连接,并且池管理打开和关闭连接。您的代码只会从池中获得可用连接,并在完成时返回。

看到这个(相当通用)Wikipedia article

一些众所周知的池是DBCPC3P0

+1

警告:虽然链接的Oracle文章给出了有关连接池基本工作原理的正确基本概念,但提供的代码示例不应用于生产!这是非常麻烦,不可扩展。而是使用servletcontainer提供的连接池设施。甚至Tomcat也带有内置的连接池。 – BalusC

+0

@BalusC你是对的,这可能有点混乱,所以我现在删除了这些引用。 –

+0

谢谢大家,我现在正在查看http://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html,并将弄清楚如何使用Tomcat的连接池。会问我是否还有其他问题。谢谢! – iLoop

2

有在这里吃两个问题:

  • HTTP会话超时
  • 数据库会话连接

你似乎混合两种会话概念。

HTTP会话

您需要使用客户端 - 服务器的HTTP机制,进一步熟悉。关闭浏览器不会关闭http会话。当你关闭浏览器时,你必须“关闭”代码到你的页面中。 “靠近”??绝对不是 - 在html/javascript中没有关闭的东西。但是有onunload(以及onload)。

为什么javascript/html中没有“onclose”?我认为发明http/html的人对许多偶然事件都是偏执狂。也许,理所当然。也许,我们必须理解html/http发明的思想和动机。所以,你别无选择,只能编造一个连锁事件的连锁反应。ONUNLOAD/ONLOAD是html页面事件,而不是浏览器事件。整个html机制都是页面驱动的,而不是浏览器驱动的因此,关闭浏览器时,会触发浏览器上每个选项卡的onunload事件。

您将不得不使用onunload页面通知服务器用户有意关闭会话。否则,服务器将不得不依赖于会话超时值来结束会话。如果用户在您未在onunload事件中编码的页面之一关闭浏览器,该怎么办?太糟糕了 - 这就是为什么我在每一页上写下了“在onunload上编造连锁反应”的原因。这是非常烦人和令人烦恼的。

有时。特别是对于高度数学的servlet,服务器需要很长时间才能做出响应。然后客户端页面需要一个指示来区分仍然处理响应的服务器与服务器已经死机 - 在浏览器上执行会话超时。例如http://support.microsoft.com/kb/813827(如何更改Internet Explorer中的默认保持活动超时值)。

也许,服务器应该在浏览器页面上戳一下,看看浏览器会话是否仍然存在。不。 Http是客户端拉技术。服务器无法将响应推送到客户端。为什么不?为什么这么傻?你必须阅读整个http/html心态/偏执狂才能理解。浏览器可以在服务器上戳,但反之亦然。

因此AJAX和彗星是发明/炮制的。模拟,假装服务器推送。使用ajax,你有一些服务器在客户端伪装的方法。这就是你必须做的 - 使用ajax例如jquery或gwt。我更喜欢gwt。

如果客户端计算机出现电源故障或操作系统遇到蓝屏,或者浏览器进程突然终止,该怎么办?没有机会触发任何页面的onunload事件。

数据库连接会话

Alex的回答一针见血 - 连接池。但是,在某些情况下,我需要每个会话都有一个数据库连接。嗯......我该怎么做?是的,我将连接存储为会话属性。因此,会话的数据库连接数将尽可能多。这与你目前的工作基本上具有相同的效果。

为一个无状态(尽管cookies)和推定不稳定的客户端开发有状态的web应用程序需要谨慎。如果用户在注销后按下后退按钮会怎么样?后退/前导页面可能包含一个操作,导致服务器使用数据库连接,在用户按下后退按钮之前,该连接已由注销页面关闭。或者,可能是服务器超时,原因是客户端没有在服务器上戳一段比会话保持活动超时值更长的持续时间。因此,在开发“多层”客户端 - 服务器应用程序之前,您必须坐下来记录所有意外事件,并且要充分了解http技术的思维/偏执。为了设计你的应用程序,你需要用http的强迫性强迫感染你自己。

+0

谢谢。在你的答案的第一部分 - 关于HTTP会话 - 我几乎可以肯定会话在浏览器关闭之后会暂停一段时间。但是你提醒我一个非常好的观点 - 服务器不能戳客户端。我不得不担心会话在开放的时候会随机死掉......你是否建议我服务的每个页面都有一些ajax函数,它会周期性地向服务器推送一些无关紧要的东西,仅仅是为了抠门而已? – iLoop

+0

“你是否建议每个页面都有一些定期检测服务器的ajax函数......?”阅读彗星和长轮询。 –

相关问题