6

Can someone explain how exactly prepared connection pooling using dbcp can be used? (with some example code if possible). I've figured out how to turn it on - passing a KeyedObjectPoolFactory to the PoolableConnectionFactory. But how should the specific prepared statements be defined after that? Right now I'm only using a PoolingDataSource to get connections from the pool. How do I use the prepared statements from the pool?

Brad Mace
  • 27,194
  • 17
  • 102
  • 148
Anand
  • 7,654
  • 9
  • 46
  • 60
  • What are you passing for the KeyedObjectPoolFactory? The constructor for the GenericKeyedObjectPoolFactory requires a KeyedPoolableObjectFactory, and I don't see how to create one of those that will use the Connection the PreparedStatement is for. – Chris Westin Aug 11 '12 at 19:50

3 Answers3

7

Well talking about getting connection from the pool vs getting "not-pooled" connection, do you have any change in your code :)? I bet you do not. Same way with prepared statements. Your code should not change. So, there is no useful code example to this.

You should read docs for your JDBC Datasource implementation and see what developers have to say about pooling. There is no other source of reliable info on this.

From here: This component has also the ability to pool PreparedStatements. When enabled a statement pool will be created for each Connection and PreparedStatements created by one of the following methods will be pooled:

* public PreparedStatement prepareStatement(String sql)
* public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)

So, you just keep using prepareStatement() call and your dbcp will in theory take care of pooling (i.e. if you are trying to create "select * from users u where u.name like :id", it will try to find this statement in the pool first)

Georgy Bolyuba
  • 8,355
  • 7
  • 29
  • 38
  • Really? Then why does the PoolableConnectionFactory have a parameter for statement pooling? Clearly there must be some way to set it up. Apache - as usual - is of no help. – sproketboy May 13 '11 at 19:59
  • @Dan: Care to expand your comment? Which part of my answer you disagree with? If you read the question again, author _already knows_ how to enable pooling for statements. He is wondering about changes that he needs to make in the code, if any. – Georgy Bolyuba May 15 '11 at 14:28
  • 1
    Sorry was just cranky due to the usual lack of documentation at Apache. – sproketboy May 16 '11 at 10:36
0

Here's basic code I use.

    GenericObjectPool connectionPool = new GenericObjectPool(null);
    connectionPool.setMinEvictableIdleTimeMillis(1000 * 60 * 30);
    connectionPool.setTimeBetweenEvictionRunsMillis(1000 * 60 * 30);
    connectionPool.setNumTestsPerEvictionRun(3);
    connectionPool.setTestOnBorrow(true);
    connectionPool.setTestWhileIdle(false);
    connectionPool.setTestOnReturn(false);

    props = new Properties();
    props.put("user", username);
    props.put("password", password);
    ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(url, props);

    PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, connectionPool, null, "SELECT 1", false, true);
    PoolingDataSource dataSource = new PoolingDataSource(connectionPool);
sproketboy
  • 8,967
  • 18
  • 65
  • 95
  • 3
    This can't be right. Passing null for the third argument of PoolableConnectionFactory disables PreparedStatement caching, as per http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/PoolableConnectionFactory.html#PoolableConnectionFactory(org.apache.commons.dbcp.ConnectionFactory, org.apache.commons.pool.ObjectPool, org.apache.commons.pool.KeyedObjectPoolFactory, java.lang.String, boolean, boolean) . What should be used for that argument? – Chris Westin Aug 11 '12 at 19:51
0

The thing is if you use a single Connection, it will cache PreparedStatements whether you want this or not, the only possible way to impact on this is to use DataSource properties or to use vendor-specific API. But these statements are not visible by other connections and if you prepare the same statement using another connection, it will recreate it again. So Connection Pools like DBCP under the hood allow reusing of PreparedStatements betwixt different connections (it uses PooledConnection interface instead of simple Connection), they keep track of all the statements prepared by all connections.

UPDATE: it seems I was wrong on this info, at least I couldn't find this functionality in C3P0.

Stanislav Bashkyrtsev
  • 14,470
  • 7
  • 42
  • 45