2 bensharp bensharp 于 2013.07.14 22:34 提问

c3p0连接池中获取的Connection对象的close()方法是真的把连接给关闭了?

自己做写了一个管理数据源的DBManager,构想中从数据源里面获取的Connection使用完之后执行close()方法,然后把Connection对象闲置回连接池中。 但是测试出来的结果好像每次执行close()之后connection就销毁了。
代码如下:

DBManager.java

    package ben.DBUtils;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.log4j.Logger;

/**
 * Created with IntelliJ IDEA.
 * User: Ben
 * Date: 13-7-3
 * Time: 下午5:06
 * To change this template use File | Settings | File Templates.
 */
public class DBManager {
    //保存数据库连接池的容器
    private static HashMap<String, ComboPooledDataSource> datasourceMap = new HashMap<String, ComboPooledDataSource>();
    private final static ThreadLocal<Connection> conns = new ThreadLocal<Connection>();
    private static Logger logger = Logger.getLogger(DBManager.class);

    static {
        InitDataSource(null);
    }


    /**
     * 初始化连接池
     * */
    private final static void InitDataSource(Properties dbProperties){
        try{
            if (dbProperties == null){
                dbProperties = new Properties();
                dbProperties.load(DBManager.class.getClassLoader().getResourceAsStream("dbInfo.properties"));
            }
            //获取数据源名称
            Set<String> keys = new HashSet<String>();
            for (Object key : dbProperties.keySet()){
                String skey = (String)key;
                Integer point = skey.indexOf(".");
                keys.add(skey.substring(0, point));
            }

            //实例化DataSource并放入容器中
            for (String key : keys)
            {
                ComboPooledDataSource ds = new ComboPooledDataSource();
                ds.setDriverClass(dbProperties.getProperty(key + "." + "Driver"));
                ds.setJdbcUrl(dbProperties.getProperty(key + "." + "Url"));
                ds.setUser(dbProperties.getProperty(key + "." + "User"));
                ds.setPassword(dbProperties.getProperty(key + "." + "Password"));
                ds.setMaxPoolSize(Integer.parseInt(dbProperties.getProperty(key + "." + "MaxPoolSize")));
                ds.setMinPoolSize(Integer.parseInt(dbProperties.getProperty(key + "." + "MinPoolSize")));
                ds.setMaxIdleTime(Integer.parseInt(dbProperties.getProperty(key + "." + "MaxIdleTime")));
                ds.setInitialPoolSize(Integer.parseInt(dbProperties.getProperty(key + "." + "InitialPoolSize")));
                ds.setAcquireIncrement(Integer.parseInt(dbProperties.getProperty(key + "." + "AcquireIncrement")));
                ds.setAcquireRetryAttempts(Integer.parseInt(dbProperties.getProperty(key + "." + "AcquireRetryAttempts")));
                ds.setAcquireRetryDelay(Integer.parseInt(dbProperties.getProperty(key + "." + "AcquireRetryDelay")));
                ds.setMaxStatements(Integer.parseInt(dbProperties.getProperty(key + "." + "MaxStatements")));
                ds.setIdleConnectionTestPeriod(Integer.parseInt(dbProperties.getProperty(key + "." + "IdleConnectionTestPeriod")));
                ds.setCheckoutTimeout(Integer.parseInt(dbProperties.getProperty(key + "." + "CheckoutTimeout")));
                ds.setTestConnectionOnCheckin(Boolean.parseBoolean(dbProperties.getProperty(key + "." + "TestConnectionOnCheckin")));
                ds.setTestConnectionOnCheckout(Boolean.parseBoolean(dbProperties.getProperty(key + "." + "TestConnectionOnCheckout")));

                datasourceMap.put(key, ds);

                Connection conn = getConnection(key);
                DatabaseMetaData metaData = conn.getMetaData();
                logger.info("Using DataSource: " + conn.getClass().getName());
                closeConnection();
            }

        }
        catch (Exception e){
            logger.error("DataSource Error:" + e.toString());
        }
    }

    /**
     * 断开连接池
     * */
    public  final static  void closeDataSource(String dataSourceName){
        try{
            ComboPooledDataSource dataSource = datasourceMap.get(dataSourceName);
            dataSource.close();
        }
        catch (Exception e){
            logger.error("Unable to destroy DataSource! " + e.toString());
        }
    }

    /**
     * 获取连接
     * @return Connection
     * */
    public final static Connection getConnection(String dataSourceName) throws SQLException{
        Connection conn = conns.get();
        if (conn == null || conn.isClosed()){
            ComboPooledDataSource dataSource = datasourceMap.get(dataSourceName);
            conn = dataSource.getConnection();
            conns.set(conn);
        }

        return conn;
    }

    /**
     * 关闭连接
     * */
    public final static void closeConnection(){
        Connection conn = conns.get();
        try{
            if (conn != null && !conn.isClosed()){
                conn.setAutoCommit(true);
                conn.close();
            }
        }
        catch (SQLException ex){
            logger.error("Unable to close connection! " + ex.toString());
        }
        finally {
            conns.remove();
            //conns.set(null);
        }
    }

}

dbInfo.properties

    DemoData.AcquireIncrement         = 2
DemoData.AcquireRetryAttempts     = 30
DemoData.AcquireRetryDelay        = 1000
DemoData.CheckoutTimeout          = 3000
DemoData.Driver                   = com.microsoft.sqlserver.jdbc.SQLServerDriver
DemoData.IdleConnectionTestPeriod = 18000
DemoData.InitialPoolSize          = 2
DemoData.MaxIdleTime              = 300
DemoData.MaxPoolSize              = 100
DemoData.MaxStatements            = 1000
DemoData.MinPoolSize              = 2
DemoData.Password                 = 123
DemoData.TestConnectionOnCheckin  = false
DemoData.TestConnectionOnCheckout = false
DemoData.Url                      = jdbc:sqlserver://localhost:1433;DatabaseName=DemoData
DemoData.User                     = sa

测试代码:TestDBManager.java

    package ben.DBUtils;

import java.sql.Connection;

/**
 * Created with IntelliJ IDEA.
 * User: Ben
 * Date: 13-7-6
 * Time: 上午12:28
 * To change this template use File | Settings | File Templates.
 */
public class TestDBManager {
    public static void main(String[] args) {
        for (Integer i=0; i<10; i++){
            try{
                System.out.println(DBManager.getConnection("DemoData"));
                DBManager.closeConnection();
                System.out.println("---------------------------");

            }
            catch (Exception ex){
                ex.printStackTrace();
            }
        }

    }
}

打印出来的结果每次都不一样

com.mchange.v2.c3p0.impl.NewProxyConnection@ff5c225

com.mchange.v2.c3p0.impl.NewProxyConnection@5bafcc2c

com.mchange.v2.c3p0.impl.NewProxyConnection@ded0b93

com.mchange.v2.c3p0.impl.NewProxyConnection@25057fe

com.mchange.v2.c3p0.impl.NewProxyConnection@198ad24a

com.mchange.v2.c3p0.impl.NewProxyConnection@1228bd68

com.mchange.v2.c3p0.impl.NewProxyConnection@36db09fa

com.mchange.v2.c3p0.impl.NewProxyConnection@35886ba1

com.mchange.v2.c3p0.impl.NewProxyConnection@17d8986

com.mchange.v2.c3p0.impl.NewProxyConnection@2bb9e538

1个回答

ToBeJavaer
ToBeJavaer   2016.11.02 14:33

你的finally里面的 conns.remove(); 是干啥的?

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!