001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.dbcp2.managed; 019import java.sql.Connection; 020 021import javax.management.ObjectName; 022 023import org.apache.commons.dbcp2.DelegatingPreparedStatement; 024import org.apache.commons.dbcp2.PStmtKey; 025import org.apache.commons.dbcp2.PoolableConnection; 026import org.apache.commons.dbcp2.PoolableConnectionFactory; 027import org.apache.commons.dbcp2.PoolingConnection; 028import org.apache.commons.pool2.KeyedObjectPool; 029import org.apache.commons.pool2.PooledObject; 030import org.apache.commons.pool2.impl.GenericKeyedObjectPool; 031import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig; 032import org.apache.commons.pool2.impl.DefaultPooledObject; 033 034/** 035 * A {@link PoolableConnectionFactory} that creates {@link PoolableManagedConnection}s. 036 * 037 * @since 2.0 038 */ 039public class PoolableManagedConnectionFactory extends PoolableConnectionFactory { 040 041 /** Transaction registry associated with connections created by this factory */ 042 private final TransactionRegistry transactionRegistry; 043 044 /** 045 * Create a PoolableManagedConnectionFactory and attach it to a connection pool. 046 * 047 * @param connFactory XAConnectionFactory 048 */ 049 public PoolableManagedConnectionFactory(XAConnectionFactory connFactory, 050 ObjectName dataSourceJmxName) { 051 super(connFactory, dataSourceJmxName); 052 this.transactionRegistry = connFactory.getTransactionRegistry(); 053 } 054 055 /** 056 * Uses the configured XAConnectionFactory to create a {@link PoolableManagedConnection}. 057 * Throws <code>IllegalStateException</code> if the connection factory returns null. 058 * Also initializes the connection using configured initialization sql (if provided) 059 * and sets up a prepared statement pool associated with the PoolableManagedConnection 060 * if statement pooling is enabled. 061 */ 062 @Override 063 synchronized public PooledObject<PoolableConnection> makeObject() throws Exception { 064 Connection conn = getConnectionFactory().createConnection(); 065 if (conn == null) { 066 throw new IllegalStateException("Connection factory returned null from createConnection"); 067 } 068 initializeConnection(conn); 069 if(getPoolStatements()) { 070 conn = new PoolingConnection(conn); 071 GenericKeyedObjectPoolConfig config = new GenericKeyedObjectPoolConfig(); 072 config.setMaxTotalPerKey(-1); 073 config.setBlockWhenExhausted(false); 074 config.setMaxWaitMillis(0); 075 config.setMaxIdlePerKey(1); 076 config.setMaxTotal(getMaxOpenPreparedStatements()); 077 KeyedObjectPool<PStmtKey,DelegatingPreparedStatement> stmtPool = 078 new GenericKeyedObjectPool<>((PoolingConnection)conn, config); 079 ((PoolingConnection)conn).setStatementPool(stmtPool); 080 ((PoolingConnection) conn).setCacheState(getCacheState()); 081 } 082 return new DefaultPooledObject<PoolableConnection>( 083 new PoolableManagedConnection(transactionRegistry, conn, getPool())); 084 } 085}