如何在Java Servlet应用程序上为每个用户创建一个数据库连接?

时间:2011-07-24 00:10:43

标签: java mysql servlets connection-pooling

我正在使用Java Servlets的网站上工作,我的研究表明,最好每个用户保持一个数据库连接(而不是只有一个连接一直在后台或每次都连接到数据库)需要进行交易)。但是,我不知道如何做到这一点。我目前正在做的是在我的数据访问对象类中我有一个

private static Connection conn;

我有HTTPSessionListener - sessionCreated事件我使用此静态“conn”变量连接到数据库,并在sessionDestroyed事件中断开“conn”变量:< / p>

...在我的“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个浏览器,但即使我关闭了一个浏览器上有我的网站,会话也不会立即死亡,我不知道到底发生了什么。我所知道的是,有时我会得到一个例外,说“连接关闭后不允许任何交易”。

2 个答案:

答案 0 :(得分:5)

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

见此(相当通用)Wikipedia article

一些众所周知的游泳池是DBCPC3P0

答案 1 :(得分:2)

这里有两个问题:

  • http session timeout
  • 数据库会话连接

您似乎在混合两个会话概念。

HTTP会话

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

为什么javascript / html中没有“onclose”?我认为发明http / html的人在许多突发事件中都是偏执狂。或许,这是正确的。也许,我们必须了解html / http发明的思维方式和动机。所以,你别无选择,只能编造onunload事件的连锁反应。 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事件。

数据库连接会话

亚历克斯的答案触及钉子连接池。但是,有些情况下我需要在每个会话中建立数据库连接。嗯......我该怎么办?是的,我将连接存储为会话属性。因此,存在与会话一样多的数据库连接。其中,与您目前正在做的事情基本相同。

为无国籍人(尽管有cookie)和推测不稳定的客户开发有状态的Web应用程序需要谨慎。如果用户在退出后按下后退按钮怎么办? backing / prev页面可能包含一个操作,该操作使服务器使用db连接,该连接在用户按下后退按钮之前已由注销页面关闭。或者,由于客户端没有在服务器上戳过持续时间超过会话保持活动超时值的服务器,服务器可能会超时。

因此,在开发“多层”客户端 - 服务器应用程序之前,您必须坐下来确定所有意外情况,并充分了解http技术的思维模式/偏执狂。为了设计你的应用程序,你需要用http的强迫性痴迷来感染自己。