1

I'm using JBoss AS 7.1 as a server and I have my DataSource configured with pooling. 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. 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.

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. So this might not be the right path.

  2. If I try to store/recall the Connection object like 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);
    

    it throws this exception:

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



My question is: How do I properly keep my connection opened?

Thanks

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
sebster
  • 1,322
  • 2
  • 18
  • 29
  • 1
    Maybe could you elaborate why the "session variables" are required? Keeping the DB connections seems to thwart J2ee principles of connection pooling... – Gyro Gearless Sep 11 '13 at 19:06
  • I know it's against J2ee principles... I tried to sustain my case but the DB Admin. is insisting he needs the session variables for each client connection. Maybe for tracking purposes. I honestly do not get him. I told him session tracking is supposed to be the job of the server app. not the DB. – sebster Sep 11 '13 at 19:13

2 Answers2

6

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. 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.


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. Once you have used it, close it.
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • Thanks for the quick reply. If I understand correctly this means that the DB session variables are allocated only for the user that owns the schema to which I'm connecting. If this is the case then how can I assign a database SID for each connection in the pool(cause this is what I suppose the DB Admin. needs)? – sebster Sep 11 '13 at 19:09
  • @sebster yes, the DB session variables will belong to the user you've configured in your datasource. Looks like you want to handle a different connection credentials per logged user, right? – Luiggi Mendoza Sep 11 '13 at 19:14
  • Yes, that's what I managed to understand from the DB Admin. Why he wants that, no idea. What he wants sounds like some sort of session tracking but DB side. I tried to tell him that I can implement a session tracking mechanism server side but the discussion ended with him insisting he needs this. Is there a way to implement that or it's an absurd request? – sebster Sep 11 '13 at 19:18
  • 1
    @sebster please read http://stackoverflow.com/q/6500452/1065197. If your DBA really insists into you trying to implement something like this, then you should talk to the project administrator or software architect or somebody that has enough *power* to show him the trade-off (specially the high cost) of implementing something like this, especially performance problems, easily testable by manually opening-closing a database connection in the servlet `doGet` or `doPost` and executing 1000 (this metric can vary) requests on that servlet – Luiggi Mendoza Sep 11 '13 at 19:35
  • Gracias Luiggi!.. you helped me shed some light on this one. I'll talk to the project manager and see how we can "manage" the DBA. Cheers! – sebster Sep 11 '13 at 20:04
2

Your DBA is basically requiring you to avoid connection pooling by making the database connection equivalent to the user's session.

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. The DBA may have to adapt to the idea that he'll need to track state in a different way, e.g. 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.

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.

John Bickers
  • 481
  • 2
  • 6
  • Thanks for the answer. Regarding the functionality that opens/closes the DB conn: How is this supposed to be done in conjunction with a JBoss configured DataSource? Cause using DriverManager to get a connection doesn't seem right to me. – sebster Sep 11 '13 at 19:53