469,347 Members | 18,544 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,347 developers. It's quick & easy.

most efficient way to get a connection from a connection pool

Having recently load-tested the application we are developing I noticed that
one of the most expensive (time-wise) calls was my fetch of a db-connection
from the defined db-pool. At present I fetch my connections using :
private Connection getConnection() throws SQLException {
try {
Context jndiCntx = new InitialContext();
DataSource ds =
(DataSource)
jndiCntx.lookup("java:comp/env/jdbc/txDatasource");
return ds.getConnection();
} catch (NamingException ne) {
myLog.error(this.makeSQLInsertable("getConnection - could not
find connection"));
throw new EJBException(ne);
}
}
In other parts of the code, not developed by the same team, I've seen the
same task accomplished by :

private Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:weblogic:jts:FTP ool");
}

From the performance-measurements I made the latter seems to be much more
efficient (time-wise). To give you some metrics:

The first version took a total of 75724ms for a total of 7224 calls which
gives ~ 11ms/call
The second version took a total of 8127ms for 11662 calls which gives
~0,7ms/call

I'm no JDBC guru som i'm probably missing something vital here. One
suspicion I have is that the second call first find the jdbc-pool and after
that makes the very same (DataSource)
jndiCntx.lookup("java:comp/env/jdbc/txDatasource") in order to fetch the
actual connection anyway. If that is true then my comparison is plain wrong
since one call is part of the second. If not, then the second version sure
seems a lot faster.

Apart from the obvious performance-differences in the two above approaches,
is there any other difference one should be aware of (transaction-context
for instance) between the two ? Basically I'm working in an EJB-environment
on weblogic 7.0 and looking for the most efficient way to get hold of a
db-connection in code. Comments anyone ?

//Linus Nikander - li***@nikander.net
Jul 17 '05 #1
4 5906
The question is whether the delay is in the DataSource itself, or in the
JNDI call. Try keeping the DataSource reference (see the ServiceLocator
pattern http://java.sun.com/blueprints/patte...ceLocator.html) and
then see what happens.

David

"Linus Nikander" <li***@nikander.net> wrote in message
news:_g*****************@news1.bredband.com...
Having recently load-tested the application we are developing I noticed that one of the most expensive (time-wise) calls was my fetch of a db-connection from the defined db-pool. At present I fetch my connections using :
private Connection getConnection() throws SQLException {
try {
Context jndiCntx = new InitialContext();
DataSource ds =
(DataSource)
jndiCntx.lookup("java:comp/env/jdbc/txDatasource");
return ds.getConnection();
} catch (NamingException ne) {
myLog.error(this.makeSQLInsertable("getConnection - could not
find connection"));
throw new EJBException(ne);
}
}
In other parts of the code, not developed by the same team, I've seen the
same task accomplished by :

private Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:weblogic:jts:FTP ool");
}

From the performance-measurements I made the latter seems to be much more
efficient (time-wise). To give you some metrics:

The first version took a total of 75724ms for a total of 7224 calls which
gives ~ 11ms/call
The second version took a total of 8127ms for 11662 calls which gives
~0,7ms/call

I'm no JDBC guru som i'm probably missing something vital here. One
suspicion I have is that the second call first find the jdbc-pool and after that makes the very same (DataSource)
jndiCntx.lookup("java:comp/env/jdbc/txDatasource") in order to fetch the
actual connection anyway. If that is true then my comparison is plain wrong since one call is part of the second. If not, then the second version sure
seems a lot faster.

Apart from the obvious performance-differences in the two above approaches, is there any other difference one should be aware of (transaction-context
for instance) between the two ? Basically I'm working in an EJB-environment on weblogic 7.0 and looking for the most efficient way to get hold of a
db-connection in code. Comments anyone ?

//Linus Nikander - li***@nikander.net

Jul 17 '05 #2
You're initializing everything each time. That equates directly to
time. Now, I'm kind of assuming that you're doing this in a web
implementation, so your milage may vary.

Create a Singleton object that contains the DataSource object (only
one for the whole app and shared across users). Initialize it either
when the app starts up or say when the first user logs into the app
after a restart. Then your calls to get the connection will look more
like the second sample you provided.

Expand|Select|Wrap|Line Numbers
  1. public void init(ServletConfig config) throws ServletException {
  2. super.init(config) ;
  3.  
  4. DatabaseResources dbResources = DatabaseResources.getInstance() ;
  5.  
  6. Context context = null ;
  7.  
  8. try{
  9. Hashtable environment = new Hashtable() ;
  10. environment.put(Context.INITIAL_CONTEXT_FACTORY,
  11. "com.ibm.websphere.naming.WsnInitialContextFactory") ;
  12.  
  13. context = new InitialContext(environment) ;
  14.  
  15. DataSource dbSource = (DataSource) context.lookup(
  16. getServletContext().getInitParameter("dataSourceName")) ;
  17.  
  18. dbResources.setDataSource(dbSource) ;
  19. context.close() ;
  20. }
  21. catch(Exception theException){
  22. System.err.println(theException.toString() + " : Generated in "
  23. + getClass().getName() + ".init() method") ;
  24. theException.printStackTrace() ;
  25. }
  26. }
  27.  
  28.  
  29. Now, here's the code for the DatabaseResources singleton object
  30.  
  31. /**
  32. * Gets the instance
  33. * @return Returns a DatabaseResources
  34. */
  35. public static DatabaseResources getInstance() {
  36. if( instance == null )
  37. instance = new DatabaseResources() ;
  38. return instance;
  39. }
  40.  
  41.  
  42. Now, here's the code to get the connection.  This exists in a
  43. superclass for all of my database access objects so this code only
  44. exists once in the app.
  45.  
  46. /**
  47. * Initialize the database connection with the provided user id &
  48. password
  49. * @param String userID
  50. * @param String password
  51. * @throws SQLException
  52. */
  53. public void init(String userID, String password) throws SQLException
  54. {
  55. DatabaseResources dbResources = DatabaseResources.getInstance() ;
  56. DataSource dataSource = dbResources.getDataSource() ;
  57. connection = dataSource.getConnection( userID, password ) ;
  58. }
  59.  
  60.  
  61.  
Since all of my Classes that have to do database access ultimately
subclass the class where init(String, String) is located, it's always
available and makes getting the connection a single line call. One
important note. init() is called inside a try{} and in the finally{}
before we leave the method and after we've done the data operations I
make the necessary calls to close the connections and such. This is
very important if you don't want hanging connections which make your
application server very unhappy.
"Linus Nikander" <li***@nikander.net> wrote in message news:<_g*****************@news1.bredband.com>...
Having recently load-tested the application we are developing I noticed that
one of the most expensive (time-wise) calls was my fetch of a db-connection
from the defined db-pool. At present I fetch my connections using :
private Connection getConnection() throws SQLException {
try {
Context jndiCntx = new InitialContext();
DataSource ds =
(DataSource)
jndiCntx.lookup("java:comp/env/jdbc/txDatasource");
return ds.getConnection();
} catch (NamingException ne) {
myLog.error(this.makeSQLInsertable("getConnection - could not
find connection"));
throw new EJBException(ne);
}
}
In other parts of the code, not developed by the same team, I've seen the
same task accomplished by :

private Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:weblogic:jts:FTP ool");
}

From the performance-measurements I made the latter seems to be much more
efficient (time-wise). To give you some metrics:

The first version took a total of 75724ms for a total of 7224 calls which
gives ~ 11ms/call
The second version took a total of 8127ms for 11662 calls which gives
~0,7ms/call

I'm no JDBC guru som i'm probably missing something vital here. One
suspicion I have is that the second call first find the jdbc-pool and after
that makes the very same (DataSource)
jndiCntx.lookup("java:comp/env/jdbc/txDatasource") in order to fetch the
actual connection anyway. If that is true then my comparison is plain wrong
since one call is part of the second. If not, then the second version sure
seems a lot faster.

Apart from the obvious performance-differences in the two above approaches,
is there any other difference one should be aware of (transaction-context
for instance) between the two ? Basically I'm working in an EJB-environment
on weblogic 7.0 and looking for the most efficient way to get hold of a
db-connection in code. Comments anyone ?

//Linus Nikander - li***@nikander.net

Jul 17 '05 #3
Thank you for your reply. What you say makes perfect sense. And as somebody
else already pointed out what I'm looking for is to implement the service
locator pattern (This will also benifit all our EBJs since they also perform
JNDI-lookups every single time). Thanks to you I don't even have to code it
! it'll be interesting to see how big a performance gain this will turn out
to be.
//linus
"Jason" <jp*****@tva.gov> wrote in message
news:47**************************@posting.google.c om...
You're initializing everything each time. That equates directly to
time. Now, I'm kind of assuming that you're doing this in a web
implementation, so your milage may vary.

Create a Singleton object that contains the DataSource object (only
one for the whole app and shared across users). Initialize it either
when the app starts up or say when the first user logs into the app
after a restart. Then your calls to get the connection will look more
like the second sample you provided.

Expand|Select|Wrap|Line Numbers
  1.  public void init(ServletConfig config) throws ServletException {
  2.  super.init(config) ;
  3.  DatabaseResources dbResources = DatabaseResources.getInstance() ;
  4.  Context context = null ;
  5.  try{
  6.  Hashtable environment = new Hashtable() ;
  7.  environment.put(Context.INITIAL_CONTEXT_FACTORY,
  8.  "com.ibm.websphere.naming.WsnInitialContextFactory") ;
  9.  context = new InitialContext(environment) ;
  10.  DataSource dbSource = (DataSource) context.lookup(
  11.  getServletContext().getInitParameter("dataSourceName")) ;
  12.  dbResources.setDataSource(dbSource) ;
  13.  context.close() ;
  14.  }
  15.  catch(Exception theException){
  16.  System.err.println(theException.toString() + " : Generated in "
  17.  + getClass().getName() + ".init() method") ;
  18.  theException.printStackTrace() ;
  19.  }
  20.  }
  21.  Now, here's the code for the DatabaseResources singleton object
  22.  /**
  23.  * Gets the instance
  24.  * @return Returns a DatabaseResources
  25.  */
  26.  public static DatabaseResources getInstance() {
  27.  if( instance == null )
  28.  instance = new DatabaseResources() ;
  29.  return instance;
  30.  }
  31.  Now, here's the code to get the connection.  This exists in a
  32.  superclass for all of my database access objects so this code only
  33.  exists once in the app.
  34.  /**
  35.  * Initialize the database connection with the provided user id &
  36.  password
  37.  * @param String userID
  38.  * @param String password
  39.  * @throws SQLException
  40.  */
  41.  public void init(String userID, String password) throws SQLException
  42.  {
  43.  DatabaseResources dbResources = DatabaseResources.getInstance() ;
  44.  DataSource dataSource = dbResources.getDataSource() ;
  45.  connection = dataSource.getConnection( userID, password ) ;
  46.  }
  47.  

Since all of my Classes that have to do database access ultimately
subclass the class where init(String, String) is located, it's always
available and makes getting the connection a single line call. One
important note. init() is called inside a try{} and in the finally{}
before we leave the method and after we've done the data operations I
make the necessary calls to close the connections and such. This is
very important if you don't want hanging connections which make your
application server very unhappy.
"Linus Nikander" <li***@nikander.net> wrote in message

news:<_g*****************@news1.bredband.com>...
Having recently load-tested the application we are developing I noticed that one of the most expensive (time-wise) calls was my fetch of a db-connection from the defined db-pool. At present I fetch my connections using :
private Connection getConnection() throws SQLException {
try {
Context jndiCntx = new InitialContext();
DataSource ds =
(DataSource)
jndiCntx.lookup("java:comp/env/jdbc/txDatasource");
return ds.getConnection();
} catch (NamingException ne) {
myLog.error(this.makeSQLInsertable("getConnection - could not find connection"));
throw new EJBException(ne);
}
}
In other parts of the code, not developed by the same team, I've seen the same task accomplished by :

private Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:weblogic:jts:FTP ool");
}

From the performance-measurements I made the latter seems to be much more efficient (time-wise). To give you some metrics:

The first version took a total of 75724ms for a total of 7224 calls which gives ~ 11ms/call
The second version took a total of 8127ms for 11662 calls which gives
~0,7ms/call

I'm no JDBC guru som i'm probably missing something vital here. One
suspicion I have is that the second call first find the jdbc-pool and after that makes the very same (DataSource)
jndiCntx.lookup("java:comp/env/jdbc/txDatasource") in order to fetch the
actual connection anyway. If that is true then my comparison is plain wrong since one call is part of the second. If not, then the second version sure seems a lot faster.

Apart from the obvious performance-differences in the two above approaches, is there any other difference one should be aware of (transaction-context for instance) between the two ? Basically I'm working in an EJB-environment on weblogic 7.0 and looking for the most efficient way to get hold of a
db-connection in code. Comments anyone ?

//Linus Nikander - li***@nikander.net

Jul 17 '05 #4
me
You dont need to be getting the InitalContext and the DataSource each time.
Wrap in something like a getConnection method, stick that inside of an
AbstractDAO
and have each DAO extend the AbstractDAO, then to get the connection, just
do:
Connection con = getConnection();
By the same token, you can have a cleanup method that releases stuff also
and put that into
the AbstractDAO. This makes for a much cleaner implementation, and also
makes the database
stuff easier to do, e.g.,., use toad to develop sql, stick sql into the dao,
make value object(s)
from the resultset, and ship it/them back to the caller.

public class AbstractDAO {
static DataSource ds = null;
static Context ctx = null;
public getConnection() {
if (ctx == null) ctx = new InitialContext();
if (ds == null) ds = ctx.lookup("java:comp/env/jdbc/txDatasource");
return ds.getConnection();
}
}

or you can use a static initializer, either will work.
Hope this helps...
--S

"Linus Nikander" <li***@nikander.net> wrote in message
news:_g*****************@news1.bredband.com...
Having recently load-tested the application we are developing I noticed that one of the most expensive (time-wise) calls was my fetch of a db-connection from the defined db-pool. At present I fetch my connections using :
private Connection getConnection() throws SQLException {
try {
Context jndiCntx = new InitialContext();
DataSource ds =
(DataSource)
jndiCntx.lookup("java:comp/env/jdbc/txDatasource");
return ds.getConnection();
} catch (NamingException ne) {
myLog.error(this.makeSQLInsertable("getConnection - could not
find connection"));
throw new EJBException(ne);
}
}
In other parts of the code, not developed by the same team, I've seen the
same task accomplished by :

private Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:weblogic:jts:FTP ool");
}

From the performance-measurements I made the latter seems to be much more
efficient (time-wise). To give you some metrics:

The first version took a total of 75724ms for a total of 7224 calls which
gives ~ 11ms/call
The second version took a total of 8127ms for 11662 calls which gives
~0,7ms/call

I'm no JDBC guru som i'm probably missing something vital here. One
suspicion I have is that the second call first find the jdbc-pool and after that makes the very same (DataSource)
jndiCntx.lookup("java:comp/env/jdbc/txDatasource") in order to fetch the
actual connection anyway. If that is true then my comparison is plain wrong since one call is part of the second. If not, then the second version sure
seems a lot faster.

Apart from the obvious performance-differences in the two above approaches, is there any other difference one should be aware of (transaction-context
for instance) between the two ? Basically I'm working in an EJB-environment on weblogic 7.0 and looking for the most efficient way to get hold of a
db-connection in code. Comments anyone ?

//Linus Nikander - li***@nikander.net

Jul 17 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by cwertman | last post: by
1 post views Thread by =?Utf-8?B?UVNJRGV2ZWxvcGVy?= | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by suresh191 | last post: by
1 post views Thread by Marylou17 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.