C3P0属性设置和数据库连接池的获取

来源:互联网 发布:leslie矩阵模型 编辑:程序博客网 时间:2024/06/14 04:45
在C3p0构建时,有驱动相关信息及数据库连接池相关的属性设置,及连接的获取,今天我们先来看一下,驱动相关信息及数据库连接池相关的属性设置,在连接的获取。 
从下面几句开始, 
Java代码  收藏代码
  1. cpDSource = new ComboPooledDataSource();  
  2. //设置DriverManagerDataSource驱动相关信息  
  3. cpDSource.setDriverClass(props.getProperty("driver"));  
  4. cpDSource.setJdbcUrl(props.getProperty("url"));  
  5. cpDSource.setUser(props.getProperty("user"));  
  6. cpDSource.setPassword(props.getProperty("password"));  

//AbstractComboPooledDataSource的两个关键内部成员DriverManagerDataSource,WrapperConnectionPoolDataSource 
Java代码  收藏代码
  1. public AbstractComboPooledDataSource(boolean autoregister)  
  2.     {  
  3.         //  
  4.         super(autoregister);  
  5.     //新建驱动数据源管理器  
  6.         dmds = new DriverManagerDataSource();  
  7.     //新建数据库连接池  
  8.         wcpds = new WrapperConnectionPoolDataSource();  
  9.     //设置数据连接池的数据源驱动管理器  
  10.         wcpds.setNestedDataSource(dmds);  
  11.         try  
  12.         {  
  13.             setConnectionPoolDataSource(wcpds);  
  14.         }  
  15.         catch(PropertyVetoException e)  
  16.         {  
  17.             logger.log(MLevel.WARNING, "Hunh??? This can't happen. We haven't set up any listeners to veto the property change yet!", e);  
  18.             throw new RuntimeException((new StringBuilder()).append("Hunh??? This can't happen. We haven't set up any listeners to veto the property change yet! ").append(e).toString());  
  19.         }  下载  
  20.         setUpPropertyEvents();  
  21.     }  
  22. }  
  23. //设置driverClass  
  24. public void setDriverClass(String driverClass)  
  25.         throws PropertyVetoException  
  26.     {  
  27.         dmds.setDriverClass(driverClass);  
  28.     }  
  29.  //设置jdbcUrl  
  30.  public void setJdbcUrl(String jdbcUrl)  
  31.     {  
  32.         if(diff(dmds.getJdbcUrl(), jdbcUrl))  
  33.         {  
  34.             dmds.setJdbcUrl(jdbcUrl);  
  35.             resetPoolManager(false);  
  36.         }  
  37.     }  
  38.    //设置user  
  39.     public void setUser(String user)  
  40.     {  
  41.         if(diff(dmds.getUser(), user))  
  42.         {  
  43.             dmds.setUser(user);  
  44.             resetPoolManager(false);  
  45.         }  
  46.     }  
  47.     //设置password  
  48.     public void setPassword(String password)  
  49.     {  
  50.         if(diff(dmds.getPassword(), password))  
  51.         {  
  52.             dmds.setPassword(password);  
  53.             resetPoolManager(false);  
  54.         }  
  55.     }  

//设置WrapperConnectionPoolDataSource相关属性 
Java代码  收藏代码
  1. cpDSource.setInitialPoolSize(5);  
  2. cpDSource.setMaxPoolSize(30);  
  3. cpDSource.setMinPoolSize(5);  
  4. cpDSource.setMaxStatements(100);  
  5. cpDSource.setIdleConnectionTestPeriod(60);  
  6. cpDSource.setBreakAfterAcquireFailure(false);  
  7. cpDSource.setAcquireRetryAttempts(30);  
  8. cpDSource.setTestConnectionOnCheckout(false);  

//设置连接失败尝试连接数 下载 
Java代码  收藏代码
  1. public void setAcquireRetryAttempts(int acquireRetryAttempts)  
  2.     {  
  3.         if(diff(wcpds.getAcquireRetryAttempts(), acquireRetryAttempts))  
  4.         {  
  5.             wcpds.setAcquireRetryAttempts(acquireRetryAttempts);  
  6.             resetPoolManager(false);  
  7.         }  
  8.     }  
  9.    
  10.     public int getAcquireRetryDelay()  
  11.     {  
  12.         return wcpds.getAcquireRetryDelay();  
  13.     }  
  14.   
  15.     public void setAcquireRetryDelay(int acquireRetryDelay)  
  16.     {  
  17.         if(diff(wcpds.getAcquireRetryDelay(), acquireRetryDelay))  
  18.         {  
  19.             wcpds.setAcquireRetryDelay(acquireRetryDelay);  
  20.             resetPoolManager(false);  
  21.         }  
  22.     }  
  23.   
  24.     public boolean isAutoCommitOnClose()  
  25.     {  
  26.         return wcpds.isAutoCommitOnClose();  
  27.     }  
  28.     //设置是否自动提交  
  29.     public void setAutoCommitOnClose(boolean autoCommitOnClose)  
  30.     {  
  31.         if(diff(wcpds.isAutoCommitOnClose(), autoCommitOnClose))  
  32.         {  
  33.             wcpds.setAutoCommitOnClose(autoCommitOnClose);  
  34.             resetPoolManager(false);  
  35.         }  
  36.     }  
  37.       
  38.     public int getInitialPoolSize()  
  39.     {  
  40.         return wcpds.getInitialPoolSize();  
  41.     }  
  42.     //连接池初始化大小  
  43.     public void setInitialPoolSize(int initialPoolSize)  
  44.     {  
  45.         if(diff(wcpds.getInitialPoolSize(), initialPoolSize))  
  46.         {  
  47.             wcpds.setInitialPoolSize(initialPoolSize);  
  48.             resetPoolManager(false);  
  49.         }  
  50.     }  
  51.   
  52.     public int getMaxIdleTime()  
  53.     {  
  54.         return wcpds.getMaxIdleTime();  
  55.     }  
  56.    //maxIdleTime  
  57.     public void setMaxIdleTime(int maxIdleTime)  
  58.     {  
  59.         if(diff(wcpds.getMaxIdleTime(), maxIdleTime))  
  60.         {  
  61.             wcpds.setMaxIdleTime(maxIdleTime);  
  62.             resetPoolManager(false);  
  63.         }  下载 
  64.     }  
  65.     //maxPoolSize  
  66.     public void setMaxPoolSize(int maxPoolSize)  
  67.     {  
  68.         if(diff(wcpds.getMaxPoolSize(), maxPoolSize))  
  69.         {  
  70.             wcpds.setMaxPoolSize(maxPoolSize);  
  71.             resetPoolManager(false);  
  72.         }  
  73.     }  
  74.    //maxStatements  
  75.     public void setMaxStatements(int maxStatements)  
  76.     {  
  77.         if(diff(wcpds.getMaxStatements(), maxStatements))  
  78.         {  
  79.             wcpds.setMaxStatements(maxStatements);  
  80.             resetPoolManager(false);  
  81.         }  
  82.     }  

从上面可以看出cpDSource初始化driver相关属性,是初始化数据源驱动管理器DriverManagerDataSource的属性;初始化poolConnection相关属性,是初始化数据库连接池包装类WrapperConnectionPoolDataSource的属性。 

再看连接的获取,从下面一句开始, 
Java代码  收藏代码
  1. con = cpDSource.getConnection();  

此方法在ComboPooledDataSource和其父类中都没,追溯到AbstractComboPooledDataSource的 
父类AbstractPoolBackedDataSource 
//AbstractPoolBackedDataSource 下载 
Java代码  收藏代码
  1. public abstract class AbstractPoolBackedDataSource extends PoolBackedDataSourceBase  
  2.     implements PooledDataSource  
  3. {  
  4.     public Connection getConnection()  
  5.         throws SQLException  
  6.     {  
  7.          //获取数据库连接池管理器  
  8.         PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();  
  9.     //从数据库连接池,返回数据库连接  
  10.         return pc.getConnection();  
  11.     }  
  12. }  

先看获取数据库连接池管理器 
//获取数据库连接池管理器 
PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection(); 
    
    //获取数据库连接池管理器 
  
Java代码  收藏代码
  1. private synchronized C3P0PooledConnectionPoolManager getPoolManager()  
  2.        throws SQLException  
  3.    {  
  4.        if(poolManager == null)  
  5.        {  
  6.    //获取数据源数据库连接池  
  7.            ConnectionPoolDataSource cpds = assertCpds();  
  8.     //构建数据库连接池管理器  
  9.            poolManager = new C3P0PooledConnectionPoolManager(cpds, nullnull, getNumHelperThreads(), getIdentityToken(), getDataSourceName());  
  10.            if(logger.isLoggable(MLevel.INFO))  
  11.                logger.info((new StringBuilder()).append("Initializing c3p0 pool... ").append(toString(true)).toString());  
  12.        }  
  13.        return poolManager;  
  14.    }  
  15.    //确定数据源数据库连接池  
  16.     private synchronized ConnectionPoolDataSource assertCpds()  
  17.        throws SQLException  
  18.    {  
  19.        if(is_closed)  
  20.            throw new SQLException((new StringBuilder()).append(this).append(" has been closed() -- you can no longer use it.").toString());  
  21.       //获取数据源数据库连接池  
  22. ConnectionPoolDataSource out = getConnectionPoolDataSource();  
  23.        if(out == null)  
  24.            throw new SQLException("Attempted to use an uninitialized PoolBackedDataSource. Please call setConnectionPoolDataSource( ... ) to initialize.");  
  25.        else  
  26.            return out;  
  27.    }  

//PoolBackedDataSourceBase 下载 
Java代码  收藏代码
  1. public class PoolBackedDataSourceBase extends IdentityTokenResolvable  
  2.     implements Referenceable, Serializable  
  3. {  
  4.    //获取数据源数据库连接池  
  5. public synchronized ConnectionPoolDataSource getConnectionPoolDataSource()  
  6.     {  
  7.         return connectionPoolDataSource;  
  8.     }  
  9.      
  10.     public synchronized void setConnectionPoolDataSource(ConnectionPoolDataSource connectionPoolDataSource)  
  11.         throws PropertyVetoException  
  12.     {  
  13.         ConnectionPoolDataSource oldVal = this.connectionPoolDataSource;  
  14.         if(!eqOrBothNull(oldVal, connectionPoolDataSource))  
  15.             vcs.fireVetoableChange("connectionPoolDataSource", oldVal, connectionPoolDataSource);  
  16.         this.connectionPoolDataSource = connectionPoolDataSource;  
  17.         if(!eqOrBothNull(oldVal, connectionPoolDataSource))  
  18.             pcs.firePropertyChange("connectionPoolDataSource", oldVal, connectionPoolDataSource);  
  19.     }  
  20. }  

这个数据源数据连接池是什么呢?还记得我们前面,有讲过AbstractComboPooledDataSource的构造有这么一段 
Java代码  收藏代码
  1. public AbstractComboPooledDataSource(boolean autoregister)  
  2.     {  
  3.         super(autoregister);  
  4.         dmds = new DriverManagerDataSource();  
  5.         wcpds = new WrapperConnectionPoolDataSource();  
  6.         wcpds.setNestedDataSource(dmds);  
  7.         try  
  8.         {  
  9.         //设置数据源数据库连接池为WrapperConnectionPoolDataSource  
  10.             setConnectionPoolDataSource(wcpds);  
  11.         }  
  12.     }  

现在回到getPoolManager的构建数据库连接池管理器这一句 
Java代码  收藏代码
  1. poolManager = new C3P0PooledConnectionPoolManager(cpds, nullnull, getNumHelperThreads(), getIdentityToken(), getDataSourceName());  

//C3P0PooledConnectionPoolManager 下载 
Java代码  收藏代码
  1. public final class C3P0PooledConnectionPoolManager  
  2. {  
  3.     private static final boolean POOL_EVENT_SUPPORT = false;  
  4.     private static final CoalesceChecker COALESCE_CHECKER;  
  5.     static final Coalescer COALESCER;  
  6.     static final int DFLT_NUM_TASK_THREADS_PER_DATA_SOURCE = 3;  
  7.     ThreadPoolAsynchronousRunner taskRunner;//  
  8.     ThreadPoolAsynchronousRunner deferredStatementDestroyer;  
  9.     Timer timer;  
  10.     ResourcePoolFactory rpfact;  
  11.     Map authsToPools;  
  12.     final ConnectionPoolDataSource cpds;  
  13.     final Map propNamesToReadMethods;  
  14.     final Map flatPropertyOverrides;  
  15.     final Map userOverrides;  
  16.     final DbAuth defaultAuth;  
  17.     final String parentDataSourceIdentityToken;  
  18.     final String parentDataSourceName;  
  19.     int num_task_threads;  
  20.     static   
  21.     {  
  22.         COALESCE_CHECKER = IdentityTokenizedCoalesceChecker.INSTANCE;  
  23.         COALESCER = CoalescerFactory.createCoalescer(COALESCE_CHECKER, truefalse);  
  24.     }  
  25.     //初始化C3P0PooledConnectionPoolManager,cpds为WrapperConnectionPoolDataSource  
  26.     public C3P0PooledConnectionPoolManager(ConnectionPoolDataSource cpds, Map flatPropertyOverrides, Map forceUserOverrides, int num_task_threads, String parentDataSourceIdentityToken, String parentDataSourceName)  
  27.         throws SQLException  
  28.     {  
  29.         //任务线程数  
  30.         this.num_task_threads = 3;  
  31.         try  
  32.         {  
  33.             this.cpds = cpds;//初始化数据库连接池  
  34.             this.flatPropertyOverrides = flatPropertyOverrides;  
  35.             this.num_task_threads = num_task_threads;  
  36.             this.parentDataSourceIdentityToken = parentDataSourceIdentityToken;  
  37.             this.parentDataSourceName = parentDataSourceName;  
  38.             DbAuth auth = null;  
  39.             if(flatPropertyOverrides != null)  
  40.             {  
  41.                 String overrideUser = (String)flatPropertyOverrides.get("overrideDefaultUser");  
  42.                 String overridePassword = (String)flatPropertyOverrides.get("overrideDefaultPassword");  
  43.                 if(overrideUser == null)  
  44.                 {  
  45.                     overrideUser = (String)flatPropertyOverrides.get("user");  
  46.                     overridePassword = (String)flatPropertyOverrides.get("password");  
  47.                 }  
  48.                 if(overrideUser != null)  
  49.                     auth = new DbAuth(overrideUser, overridePassword);  
  50.             }  
  51.             if(auth == null)  
  52.             //初始化数据库验证  
  53.                 auth = C3P0ImplUtils.findAuth(cpds);  
  54.             defaultAuth = auth;  
  55.             Map tmp = new HashMap();  
  56.             BeanInfo bi = Introspector.getBeanInfo(cpds.getClass());  
  57.             PropertyDescriptor pds[] = bi.getPropertyDescriptors();  
  58.             PropertyDescriptor pd = null;  
  59.             int i = 0;  
  60.             for(int len = pds.length; i < len; i++)  
  61.             {  
  62.                 pd = pds[i];  
  63.                 String name = pd.getName();  
  64.                 Method m = pd.getReadMethod();  
  65.                 if(m != null)  
  66.                     tmp.put(name, m);  
  67.             }  
  68.   
  69.             propNamesToReadMethods = tmp;  
  70.             if(forceUserOverrides == null)  
  71.             {  
  72.                 Method uom = (Method)propNamesToReadMethods.get("userOverridesAsString");  
  73.                 if(uom != null)  
  74.                 {  
  75.                     String uoas = (String)uom.invoke(cpds, (Object[])null);  
  76.                     Map uo = C3P0ImplUtils.parseUserOverridesAsString(uoas);  
  77.                     userOverrides = uo;  
  78.                 } else  
  79.                 {  
  80.                     userOverrides = Collections.EMPTY_MAP;  
  81.                 }  
  82.             } else  
  83.             {  
  84.                 userOverrides = forceUserOverrides;  
  85.             }  
  86.   
  87.             poolsInit();  
  88.         }  
  89.         catch(Exception e)  
  90.         {  
  91.             logger.log(MLevel.FINE, null, e);  
  92.             throw SqlUtils.toSQLException(e);  
  93.         }  
  94.     }  
  95. }  
  96. //连接池初始化  
  97. private void poolsInit()  
  98.     {  
  99.         boolean privilege_spawned_threads = getPrivilegeSpawnedThreads();  
  100.         String contextClassLoaderSource = getContextClassLoaderSource();  
  101.         class _cls1ContextClassLoaderPoolsInitThread extends Thread  
  102.         {  
  103.   
  104.             public void run()  
  105.             {  
  106.             //  
  107.                 maybePrivilegedPoolsInit(privilege_spawned_threads);  
  108.             }  
  109.   
  110.             final boolean val$privilege_spawned_threads;  
  111.             final C3P0PooledConnectionPoolManager this$0;  
  112.   
  113.             _cls1ContextClassLoaderPoolsInitThread(boolean flag)  
  114.             {  
  115.                 this.this$0 = C3P0PooledConnectionPoolManager.this;  
  116.                 privilege_spawned_threads = flag;  
  117.                 super();  
  118.                 setContextClassLoader(ccl);  
  119.             }  
  120.         }  
  121.   
  122.         try  
  123.         {  
  124.             if("library".equalsIgnoreCase(contextClassLoaderSource))  
  125.             {  
  126.             //  
  127.                 Thread t = new _cls1ContextClassLoaderPoolsInitThread(privilege_spawned_threads);  
  128.                 t.start();  
  129.                 t.join();  
  130.             } else  
  131.             if("none".equalsIgnoreCase(contextClassLoaderSource))  
  132.             {  
  133.                 Thread t = new _cls1ContextClassLoaderPoolsInitThread(privilege_spawned_threads);  
  134.                 t.start();  
  135.                 t.join();  
  136.             } else  
  137.             {  
  138.                 if(logger.isLoggable(MLevel.WARNING) && !"caller".equalsIgnoreCase(contextClassLoaderSource))  
  139.                     logger.log(MLevel.WARNING, (new StringBuilder()).append("Unknown contextClassLoaderSource: ").append(contextClassLoaderSource).append(" -- should be 'caller', 'library', or 'none'. Using default value 'caller'.").toString());  
  140.                 maybePrivilegedPoolsInit(privilege_spawned_threads);  
  141.             }  
  142.         }  
  143.     }  
  144.   
  145.  private void maybePrivilegedPoolsInit(boolean privilege_spawned_threads)  
  146.     {  
  147.         if(privilege_spawned_threads)  
  148.         {  
  149.             PrivilegedAction privilegedPoolsInit = new PrivilegedAction() {  
  150.   
  151.                 public Void run()  
  152.                 {  
  153.             //委托给_poolsInit  
  154.                     _poolsInit();  
  155.                     return null;  
  156.                 }  
  157.   
  158.                 public volatile Object run()  
  159.                 {  
  160.                     return run();  
  161.                 }  
  162.   下载 
  163.                 final C3P0PooledConnectionPoolManager this$0;  
  164.   
  165.               
  166.             {  
  167.                 this.this$0 = C3P0PooledConnectionPoolManager.this;  
  168.                 super();  
  169.             }  
  170.             };  
  171.             AccessController.doPrivileged(privilegedPoolsInit);  
  172.         } else  
  173.         {  
  174.             _poolsInit();  
  175.         }  
  176.     }  
  177.     //终于找个了poolsInit的关键,初始化定时任务调度器,及死锁检测线程,及延时死锁检测线程  
  178.     private synchronized void _poolsInit()  
  179.     {  
  180.         String idStr = idString();  
  181.         timer = new Timer((new StringBuilder()).append(idStr).append("-AdminTaskTimer").toString(), true);  
  182.         int matt = getMaxAdministrativeTaskTime();  
  183.     //创建任务线程调度器  
  184.         taskRunner = createTaskRunner(num_task_threads, matt, timer, (new StringBuilder()).append(idStr).append("-HelperThread").toString());  
  185.         int num_deferred_close_threads = getStatementCacheNumDeferredCloseThreads();  
  186.         if(num_deferred_close_threads > 0)  
  187.             deferredStatementDestroyer = createTaskRunner(num_deferred_close_threads, matt, timer, (new StringBuilder()).append(idStr).append("-DeferredStatementDestroyerThread").toString());  
  188.         else  
  189.             deferredStatementDestroyer = null;  
  190.         rpfact = BasicResourcePoolFactory.createNoEventSupportInstance(taskRunner, timer);  
  191.         authsToPools = new HashMap();  
  192.     }  

从上面可以看出getPoolManager()实际上,是初始化数据库连接池管理器C3P0PooledConnectionPoolManager,初始化C3P0PooledConnectionPoolManager的
0 0