如何正确地保持JBoss中打开的连接池的数据库连接

时间:2013-09-11 18:55:29

标签: java jboss datasource connection-pooling

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

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

充分利用我遇到的两个主要问题:

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

  2. 如果我尝试存储/调用Connection对象,例如 this:

    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与托管无关   connection.org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@dee1f37



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

    由于

2 个答案:

答案 0 :(得分:6)

  

如何正确保持连接打开?

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


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

//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状态。


解释中的一些建议:

  • 不得尝试保持连接活动,这是连接池的工作。
  • 不得尝试将连接存储在任何缓存类似的结构中,这是连接池的工作。
  • 必须在您需要的最短范围内检索java.sql.Connection。使用后,关闭

答案 1 :(得分:2)

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

因此,一个选项是不使用连接池,而是滚动您自己的功能,打开/关闭用户会话周围的数据库连接。这看起来很复杂和不寻常。

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

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