简体   繁体   English

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

[英]How to properly keep a DB connection from a Connection Pool opened in JBoss

I'm using JBoss AS 7.1 as a server and I have my DataSource configured with pooling. 我正在使用JBoss AS 7.1作为服务器,并且我的DataSource配置有缓冲池。 I'm quite new to this so please excuse any rookie mistakes... after all I'm here to learn. 我对此很陌生,所以请原谅任何菜鸟错误……毕竟我是来这里学习的。

When a client logs-in it gets a connection to the database and I need to keep that connection(from the pool) open until the user logs-out or the HttpSession expires. 当客户端登录时,它将获得与数据库的连接,我需要保持该连接(从池中)处于打开状态,直到用户注销或HttpSession过期为止。 This is an absolute requirement coming from our DB Admin. 这是来自数据库管理员的绝对要求。 who says that he needs the DB session variables. 谁说他需要数据库会话变量。 I am using a servlet for all this. 我正在为此使用servlet

Playing with the possibilities I have encountered 2 major problems: 我在尝试各种可能性时遇到了两个主要问题:

  1. As far as I see JBoss automatically closes unused connections => my opened connection returns to the pool. 据我所知,JBoss自动关闭未使用的连接=>我打开的连接返回到池中。 So this might not be the right path. 因此,这可能不是正确的道路。

  2. If I try to store/recall the Connection object like this: 如果我尝试像这样存储/调用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); 

    it throws this exception: 它将引发此异常:

    java.sql.SQLException: Connection is not associated with a managed connection.org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@dee1f37 java.sql.SQLException:连接与托管连接未关联。org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@ dee1f37



My question is: How do I properly keep my connection opened? 我的问题是:如何正确保持连接打开?

Thanks 谢谢

How do I properly keep my connection opened? 如何正确保持连接打开?

You must not do that, let the connection pool handle this. 一定不要这样做,让连接池来处理。


Behind the scenes, the connection pool will keep a bunch of database connections to the database engine (MySQL, Oracle, SQL Server... depends how you configure it) in SLEEPING state. 在后台,连接池将在SLEEPING状态下保持与数据库引擎(MySQL,Oracle,SQL Server ...取决于您如何配置)的大量数据库连接。 When you execute this code: 执行此代码时:

//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();
}

You're asking to the connection pool to retrieve one of these connections available. 您要求连接池检索这些可用连接之一。 The connection pool will give you a database connection (if available) and let you use it as long as you want. 连接池将为您提供数据库连接(如果可用),并让您根据需要使用它。 Then you use it wherever you want/need and close it : 然后,您可以在任何需要的地方使用它并关闭它

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();
}

When executing connection.close() from a connection retrieved by the connection pool, you're not closing the physical database connection but notifying the connection pool this specific database connection must return to the SLEEPING state. 从连接池检索到的连接中执行connection.close() ,您不是在关闭物理数据库连接,而是通知连接池此特定的数据库连接必须返回SLEEPING状态。


Some advices from the explanation: 来自解释的一些建议:

  • You must not try to keep the connection alive, that's connection pool's job. 一定不要尝试保持连接活动,这就是连接池的工作。
  • You must not try to store the connections in any cache -like structure, that's connection pool's job. 一定不要尝试将连接存储在任何类似于缓存的结构中,这就是连接池的工作。
  • You must retrieve a java.sql.Connection in the shortest scope you will need it. 必须在需要它的最短范围内检索java.sql.Connection Once you have used it, close it. 使用完后,将其关闭

Your DBA is basically requiring you to avoid connection pooling by making the database connection equivalent to the user's session. 您的DBA基本上要求您通过使数据库连接等同于用户会话来避免连接池。

So one option is to not use the connection pool, and instead roll your own functionality that opens/closes the database connection around the user's session. 因此,一种选择是不使用连接池,而是使用自己的功能来围绕用户会话打开/关闭数据库连接。 That seems complicated and unusual though. 但是,这似乎很复杂且不寻常。

Another option is to examine the DBA's requirement. 另一种选择是检查DBA的要求。 The DBA may have to adapt to the idea that he'll need to track state in a different way, eg by using a key related to the session to store the state he needs in a table, instead of storing state in the connection layer. DBA可能必须适应他需要以不同方式跟踪状态的想法,例如,通过使用与会话相关的键来将他需要的状态存储在表中,而不是在连接层中存储状态。

Generally speaking storing state in some component's session handling is adding indirect complexity, because you start having to care about how the component handles expiry and uniqueness, as you're finding here where the HTTP session state handles this differently from the database session. 通常来说,在某些组件的会话处理中存储状态会增加间接的复杂性,因为您开始关心组件如何处理到期时间和唯一性,因为您在这里发现HTTP会话状态与数据库会话的处理方式不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM