1

我使用 JBoss AS 7.1 作为服务器,并且我的 DataSource 配置了池。我对此很陌生,所以请原谅任何菜鸟的错误......毕竟我是来这里学习的。

当客户端登录时,它会连接到数据库,我需要保持该连接(来自池)打开,直到用户注销或 HttpSession 过期。这是来自我们的数据库管理员的绝对要求。谁说他需要数据库会话变量。我正在为所有这些使用servlet

发挥我遇到的两个主要问题的可能性:

  1. 据我所知,JBoss 会自动关闭未使用的连接 => 我打开的连接返回到池中。所以这可能不是正确的道路。

  2. 如果我尝试像这样存储/调用 Connection 对象:

    private Hashtable<String, Connection> connections = new Hashtable<String, Connection>();
    
    try {
        String strDSName1 = "java:/OracleDSJNDI";
        ctx = new InitialContext();
        ds1 = (javax.sql.DataSource) ctx.lookup(strDSName1);
    
        System.out.println("Got 1'st ds.");
    
    } catch (Exception e) {
        System.out.println("ERROR getting 1'st DS : " + e);
    }
    
    connection = ds1.getConnection();
    connections.put(session.getId(), connection);
    
    conn = (Connection) connections.get(sessionID);
    

    它抛出这个异常:

    java.sql.SQLException: Connection is not associated with an managed connection.org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@dee1f37



我的问题是:如何正确保持连接打开?

谢谢

4

2 回答 2

6

如何正确保持连接打开?

不能这样做,让连接池处理这个。


在幕后,连接池将保持一堆数据库连接到数据库引擎(MySQL、Oracle、SQL Server ......取决于你如何配置它)的SLEEPING状态。当您执行此代码时:

//avoiding all the particular exceptions just for code simplicity purposes...
//in real world applications, you must handle each of these exceptions
public Connection getConnection() throws Exception {
    ctx = new InitialContext();
    ds1 = (javax.sql.DataSource) ctx.lookup(strDSName1);
    return ds1.getConnection();
}

您要求连接池检索这些可用连接之一。连接池会给你一个数据库连接(如果有的话),让你想用多久就用多久。然后你在任何你想要/需要的地方使用它并关闭它

public void foo() throws Exception {
    Connection connection = getConnection();
    //do what you want/need...

    //in the end, you close the connection
    //this is A MUST!
    connection.close();
}

从连接池检索到的连接执行connection.close()时,您不会关闭物理数据库连接,而是通知连接池此特定数据库连接必须返回到SLEEPING状态。


解释中的一些建议:

  • 不能尝试保持连接活动,这是连接池的工作。
  • 不能尝试将连接存储在任何类似缓存的结构中,这是连接池的工作。
  • 必须在需要的最短范围内检索 a java.sql.Connection。一旦你使用它,关闭它。
于 2013-09-11T19:04:29.690 回答
2

您的 DBA 基本上要求您通过使数据库连接等效于用户会话来避免连接池。

因此,一种选择是不使用连接池,而是使用您自己的功能来打开/关闭用户会话周围的数据库连接。不过,这似乎既复杂又不寻常。

另一种选择是检查 DBA 的要求。DBA 可能不得不适应他需要以不同方式跟踪状态的想法,例如通过使用与会话相关的键将他需要的状态存储在表中,而不是将状态存储在连接层中。

一般来说,在某些组件的会话处理中存储状态会增加间接的复杂性,因为您开始必须关心组件如何处理到期和唯一性,因为您在这里发现 HTTP 会话状态与数据库会话不同的处理方式。

于 2013-09-11T19:22:48.707 回答