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

在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. public int getAcquireRetryDelay()
  10. {
  11. return wcpds.getAcquireRetryDelay();
  12. }
  13. public void setAcquireRetryDelay(int acquireRetryDelay)
  14. {
  15. if(diff(wcpds.getAcquireRetryDelay(), acquireRetryDelay))
  16. {
  17. wcpds.setAcquireRetryDelay(acquireRetryDelay);
  18. resetPoolManager(false);
  19. }
  20. }
  21. public boolean isAutoCommitOnClose()
  22. {
  23. return wcpds.isAutoCommitOnClose();
  24. }
  25. //设置是否自动提交
  26. public void setAutoCommitOnClose(boolean autoCommitOnClose)
  27. {
  28. if(diff(wcpds.isAutoCommitOnClose(), autoCommitOnClose))
  29. {
  30. wcpds.setAutoCommitOnClose(autoCommitOnClose);
  31. resetPoolManager(false);
  32. }
  33. }
  34. public int getInitialPoolSize()
  35. {
  36. return wcpds.getInitialPoolSize();
  37. }
  38. //连接池初始化大小
  39. public void setInitialPoolSize(int initialPoolSize)
  40. {
  41. if(diff(wcpds.getInitialPoolSize(), initialPoolSize))
  42. {
  43. wcpds.setInitialPoolSize(initialPoolSize);
  44. resetPoolManager(false);
  45. }
  46. }
  47. 下载
  48. public int getMaxIdleTime()
  49. {
  50. return wcpds.getMaxIdleTime();
  51. }
  52. //maxIdleTime
  53. public void setMaxIdleTime(int maxIdleTime)
  54. {
  55. if(diff(wcpds.getMaxIdleTime(), maxIdleTime))
  56. {
  57. wcpds.setMaxIdleTime(maxIdleTime);
  58. resetPoolManager(false);
  59. }
  60. }
  61. //maxPoolSize
  62. public void setMaxPoolSize(int maxPoolSize)
  63. {
  64. if(diff(wcpds.getMaxPoolSize(), maxPoolSize))
  65. {
  66. wcpds.setMaxPoolSize(maxPoolSize);
  67. resetPoolManager(false);
  68. }
  69. }
  70. //maxStatements
  71. public void setMaxStatements(int maxStatements)
  72. {
  73. if(diff(wcpds.getMaxStatements(), maxStatements))
  74. {
  75. wcpds.setMaxStatements(maxStatements);
  76. resetPoolManager(false);
  77. }
  78. }

从上面可以看出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, null, null, 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. public synchronized void setConnectionPoolDataSource(ConnectionPoolDataSource connectionPoolDataSource)
  10. throws PropertyVetoException
  11. {
  12. ConnectionPoolDataSource oldVal = this.connectionPoolDataSource;
  13. if(!eqOrBothNull(oldVal, connectionPoolDataSource))
  14. vcs.fireVetoableChange("connectionPoolDataSource", oldVal, connectionPoolDataSource);
  15. this.connectionPoolDataSource = connectionPoolDataSource;
  16. if(!eqOrBothNull(oldVal, connectionPoolDataSource))
  17. pcs.firePropertyChange("connectionPoolDataSource", oldVal, connectionPoolDataSource);
  18. }
  19. }

这个数据源数据连接池是什么呢?还记得我们前面,有讲过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, null, null, 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, true, false);
  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. propNamesToReadMethods = tmp;
  69. if(forceUserOverrides == null)
  70. {
  71. Method uom = (Method)propNamesToReadMethods.get("userOverridesAsString");
  72. if(uom != null)
  73. {
  74. String uoas = (String)uom.invoke(cpds, (Object[])null);
  75. Map uo = C3P0ImplUtils.parseUserOverridesAsString(uoas);
  76. userOverrides = uo;
  77. } else
  78. {
  79. userOverrides = Collections.EMPTY_MAP;
  80. }
  81. } else
  82. {
  83. userOverrides = forceUserOverrides;
  84. }
  85. poolsInit();
  86. }
  87. catch(Exception e)
  88. {
  89. logger.log(MLevel.FINE, null, e);
  90. throw SqlUtils.toSQLException(e);
  91. }
  92. }
  93. }
  94. //连接池初始化
  95. private void poolsInit()
  96. {
  97. boolean privilege_spawned_threads = getPrivilegeSpawnedThreads();
  98. String contextClassLoaderSource = getContextClassLoaderSource();
  99. class _cls1ContextClassLoaderPoolsInitThread extends Thread
  100. {
  101. public void run()
  102. {
  103. //
  104. maybePrivilegedPoolsInit(privilege_spawned_threads);
  105. }
  106. final boolean val$privilege_spawned_threads;
  107. final C3P0PooledConnectionPoolManager this$0;
  108. _cls1ContextClassLoaderPoolsInitThread(boolean flag)
  109. {
  110. this.this$0 = C3P0PooledConnectionPoolManager.this;
  111. privilege_spawned_threads = flag;
  112. super();
  113. setContextClassLoader(ccl);
  114. }
  115. }
  116. try
  117. {
  118. if("library".equalsIgnoreCase(contextClassLoaderSource))
  119. {
  120. //
  121. Thread t = new _cls1ContextClassLoaderPoolsInitThread(privilege_spawned_threads);
  122. t.start();
  123. t.join();
  124. } else
  125. if("none".equalsIgnoreCase(contextClassLoaderSource))
  126. {
  127. Thread t = new _cls1ContextClassLoaderPoolsInitThread(privilege_spawned_threads);
  128. t.start();
  129. t.join();
  130. } else
  131. {
  132. if(logger.isLoggable(MLevel.WARNING) && !"caller".equalsIgnoreCase(contextClassLoaderSource))
  133. logger.log(MLevel.WARNING, (new StringBuilder()).append("Unknown contextClassLoaderSource: ").append(contextClassLoaderSource).append(" -- should be ‘caller‘, ‘library‘, or ‘none‘. Using default value ‘caller‘.").toString());
  134. maybePrivilegedPoolsInit(privilege_spawned_threads);
  135. }
  136. }
  137. }
  138. private void maybePrivilegedPoolsInit(boolean privilege_spawned_threads)
  139. {
  140. if(privilege_spawned_threads)
  141. {
  142. PrivilegedAction privilegedPoolsInit = new PrivilegedAction() {
  143. public Void run()
  144. {
  145. //委托给_poolsInit
  146. _poolsInit();
  147. return null;
  148. }
  149. public volatile Object run()
  150. {
  151. return run();
  152. }
  153. final C3P0PooledConnectionPoolManager this$0;
  154. {
  155. this.this$0 = C3P0PooledConnectionPoolManager.this;
  156. super();
  157. }
  158. };
  159. AccessController.doPrivileged(privilegedPoolsInit);
  160. } else
  161. {
  162. _poolsInit();
  163. }
  164. }
  165. //终于找个了poolsInit的关键,初始化定时任务调度器,及死锁检测线程,及延时死锁检测线程
  166. private synchronized void _poolsInit()
  167. {
  168. String idStr = idString();
  169. timer = new Timer((new StringBuilder()).append(idStr).append("-AdminTaskTimer").toString(), true);
  170. int matt = getMaxAdministrativeTaskTime();
  171. //创建任务线程调度器
  172. taskRunner = createTaskRunner(num_task_threads, matt, timer, (new StringBuilder()).append(idStr).append("-HelperThread").toString());
  173. int num_deferred_close_threads = getStatementCacheNumDeferredCloseThreads();
  174. if(num_deferred_close_threads > 0)
  175. deferredStatementDestroyer = createTaskRunner(num_deferred_close_threads, matt, timer, (new StringBuilder()).append(idStr).append("-DeferredStatementDestroyerThread").toString());
  176. else
  177. deferredStatementDestroyer = null;
  178. rpfact = BasicResourcePoolFactory.createNoEventSupportInstance(taskRunner, timer);
  179. authsToPools = new HashMap();
  180. }

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

时间: 2024-10-19 08:14:04

C3P0属性设置和数据库连接池的获取的相关文章

开源数据库连接池之C3P0

本篇介绍几种开源数据库连接池,同时重点讲述如何使用C3P0数据库连接池. 之前的博客已经重点讲述了使用数据库连接池的好处,即是将多次创建连接转变为一次创建而使用长连接模式.这样能减少数据库创建连接的消耗.正是由于数据库连接池的思想非常重要,所以市面上也有很多开源的数据库连接池供我们使用.主要有以下三个: DBCP数据库连接池 C3P0 数据库连接池 Tomcat内置的数据库连接池(DBCP) 本篇主要讲述C3P0数据库连接池的使用,关于另外两个数据库连接池的用法请看<开源数据库连接池之DBCP>

java攻城狮之路--复习JDBC(数据库连接池 : C3P0、DBCP)

复习数据库连接池 : C3P0.DBCP 1.数据库连接池技术的优点: •资源重用: 由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销.在减少系统消耗的基础上,另一方面也增加了系统运行环境的平稳性. •更快的系统反应速度: 数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用.此时连接的初始化工作均已完成.对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间. •新的资源分配手段: 对于多应用共享同

【转】JDBC学习笔记(8)——数据库连接池(dbcp&amp;C3P0)

转自:http://www.cnblogs.com/ysw-go/ JDBC数据库连接池的必要性 一.在使用开发基于数据库的web程序时,传统的模式基本是按一下步骤: 1)在主程序(如servlet/beans)中建立数据库连接 2)进行sql操作 3)断开数据库连接 二.这种模式开发,存在的问题: 1)普通的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接的时候都要将Connection加载进内存中,再验证用户名和密码(得花费0.05s~1s的时间).需要数据库连接

c3p0数据库连接池管理

之前已经讲过dbcp可以用于数据库连接池进行管理.另一种技术c3p0也可以用于数据库连接池管理,其中Spring等框架都是基于c3p0技术进行数据库连接池管理的. 使用之前需要引入 c3p0-0.9.5.2.jar 和 mchange-commons-java-0.2.11.jar 包,主要的类是ComboPooledDataSource,也有两种方式进行设置.一种是代码中进行设置,一种是在配置文件中设置.主要区别就是这种方式只有一个主要类ComboPooledDataSource. 他们之间可

javaweb学习总结(三十九)——数据库连接池

一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出.拓机.如下图所示: 二.使用数据库连接池优化程序性能 2.1.数据库连接池的基本概念 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性

01_数据库连接池,数据源,ResultSetMetaData,jdbc优化

 一.数据库连接池 1. 什么是连接池 传统的开发模式下,Servlet处理用户的请求,找Dao查询数据,dao会创建与数据库之间的连接,完成数据查询后会关闭数据库的链接. 这样的方式会导致用户每次请求都要向数据库建立链接而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出.宕机. 解决方案就是数据库连接池 连接池就是数据库连接对象的一个缓冲池 我们可以先创建10个数

数据库连接池(一)

一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出.拓机.如下图所示: 二.使用数据库连接池优化程序性能 2.1.数据库连接池的基本概念 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性

深入分析JavaWeb Item32 -- 数据库连接池

一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出.拓机.如下图所示: 二.使用数据库连接池优化程序性能 2.1.数据库连接池的基本概念 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性

Java 数据库连接池—转载孤傲苍狼 http://www.cnblogs.com/xdp-gacl/p/4002804.html

一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出.拓机.如下图所示: 二.使用数据库连接池优化程序性能 2.1.数据库连接池的基本概念 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性