`

数据库连接池

 
阅读更多


1:dbcp数据库连接池

1、applicationContext.xml配置:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"           

         destroy-method="close">           

     <property name="driverClassName" value="com.mysql.jdbc.Driver" />          

     <property name="url" value="jdbc:mysql://localhost:3309/test?useUnicode=true&characterEncoding=UTF-8" />          

     <property name="username" value="root" />          

     <property name="password" value="1234" />  

        <!--连接池启动时的初始化-->

     <property name="initialSize" value="1"/>

     <!--连接池的最大值-->      

     <property name="maxActive" value="500"/>

     <!-- 最大空闲值,当经过一个高峰时间后,连接池可以慢慢将已经用不到的链接慢慢释放一部分,一直减少到maxle为止 -->

     <property name="maxIdle" value="2"/>

     <!-- 最小空闲值,当空闲的连接数少于阀值时,连接池就会预申请去一些链接,以免洪峰来时来不及申请-->

     <property name="minIdle" value="1"/>

  </bean>


可以使用资源文件进行具体值的配置


2、连接池属性说明


  BasicDataSource提供了close()方法关闭数据源,所以必须设定destroy-method=”close”属性, 以便Spring容器关闭时,数据源能够正常关闭。除以上必须的数据源属性外,还有一些常用的属性:    defaultAutoCommit:设置从数据源中返回的连接是否采用自动提交机制,默认值为 true;

    defaultReadOnly:设置数据源是否仅能执行只读操作, 默认值为 false;

    maxActive:最大连接数据库连接数,设置为0时,表示没有限制;

    maxIdle:最大等待连接中的数量,设置为0时,表示没有限制;

    maxWait:最大等待秒数,单位为毫秒, 超过时间会报出错误信息;

    validationQuery:用于验证连接是否成功的查询SQL语句,SQL语句必须至少要返回一行数据, 如你可以简单地设置为:“select count(*) from user”;

    removeAbandoned:是否自我中断,默认是 false ;

    removeAbandonedTimeout:几秒后数据连接会自动断开,在removeAbandoned为true,提供该值;

    logAbandoned:是否记录中断事件, 默认为 false;

连接池配置比较

比较熟悉的开源连接池有dbcp,c3p0,proxool。对这三种连接池来说,从性能和出错率来说,proxool稍微比前两种好些。



2:c3p0连接池


<c3p0-config>

<default-config>

<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->

<property name="acquireIncrement">3</property>


<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->

<property name="acquireRetryAttempts">30</property>


<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->

<property name="acquireRetryDelay">1000</property>


<!--连接关闭时默认将所有未提交的操作回滚。Default: false -->

<property name="autoCommitOnClose">false</property>


<!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么

属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试

使用。Default: null-->

<property name="automaticTestTable">Test</property>


<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效

保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试

获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->

<property name="breakAfterAcquireFailure">false</property>


<!--当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出

SQLException,如设为0则无限期等待。单位毫秒。Default: 0 -->

<property name="checkoutTimeout">100</property>


<!--通过实现ConnectionTester或QueryConnectionTester的类来测试连接。类名需制定全路径。

Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester-->

<property name="connectionTesterClassName"></property>


<!--指定c3p0 libraries的路径,如果(通常都是这样)在本地即可获得那么无需设置,默认null即可

Default: null-->

<property name="factoryClassLocation">null</property>


<!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs.

(文档原文)作者强烈建议不使用的一个属性-->

<property name="forceIgnoreUnresolvedTransactions">false</property>


<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->

<property name="idleConnectionTestPeriod">60</property>


<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->

<property name="initialPoolSize">3</property>


<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->

<property name="maxIdleTime">60</property>


<!--连接池中保留的最大连接数。Default: 15 -->

<property name="maxPoolSize">15</property>


<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements

属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。

如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->

<property name="maxStatements">100</property>


<!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->

<property name="maxStatementsPerConnection"></property>


<!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能

通过多线程实现多个操作同时被执行。Default: 3-->

<property name="numHelperThreads">3</property>


<!--当用户调用getConnection()时使root用户成为去获取连接的用户。主要用于连接池连接非c3p0

的数据源时。Default: null-->

<property name="overrideDefaultUser">root</property>


<!--与overrideDefaultUser参数对应使用的一个参数。Default: null-->

<property name="overrideDefaultPassword">password</property>


<!--密码。Default: null-->

<property name="password"></property>


<!--定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:

测试的表必须在初始数据源的时候就存在。Default: null-->

<property name="preferredTestQuery">select id from test where id=1</property>


<!--用户修改系统配置参数执行前最多等待300秒。Default: 300 -->

<property name="propertyCycle">300</property>


<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的

时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable

等方法来提升连接测试的性能。Default: false -->

<property name="testConnectionOnCheckout">false</property>


<!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false -->

<property name="testConnectionOnCheckin">true</property>


<!--用户名。Default: null-->

<property name="user">root</property>


<!--早期的c3p0版本对JDBC接口采用动态反射代理。在早期版本用途广泛的情况下这个参数

允许用户恢复到动态反射代理以解决不稳定的故障。最新的非反射代理更快并且已经开始

广泛的被使用,所以这个参数未必有用。现在原先的动态反射与新的非反射代理同时受到

支持,但今后可能的版本可能不支持动态反射代理。Default: false-->

<property name="usesTraditionalReflectiveProxies">false</property>


<property name="automaticTestTable">con_test</property>

<property name="checkoutTimeout">30000</property>

<property name="idleConnectionTestPeriod">30</property>

<property name="initialPoolSize">10</property>

<property name="maxIdleTime">30</property>

<property name="maxPoolSize">25</property>

<property name="minPoolSize">10</property>

<property name="maxStatements">0</property>

<user-overrides user="swaldman">

</user-overrides>

</default-config>

<named-config name="dumbTestConfig">

<property name="maxStatements">200</property>

<user-overrides user="poop">

<property name="maxStatements">300</property>

</user-overrides>

</named-config>

</c3p0-config>


spring 整合

<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 

      <property name="driverClass"> 

        <value>${jdbc.driverClassName}</value> 

      </property> 

      <property name="jdbcUrl"> 

        <value>${jdbc.url}</value> 

      </property> 

      <property name="user"> 

       <value>${jdbc.username}</value> 

      </property> 

      <property name="password"> 

       <value>${jdbc.password}</value> 

      </property> 

      <property name="initialPoolSize"><value>10</value></property> 

      <property name="minPoolSize"><value>5</value></property> 

      <property name="maxPoolSize"><value>30</value></property> 

      <property name="acquireIncrement"><value>5</value></property> 

      <property name="maxIdleTime"><value>10</value></property> 

      <property name="maxStatements"><value>0</value></property> 

    </bean> 


以下几个参数是使用的基本配置参数: 

initialPoolSize: 

Number of Connections a pool will try to acquire upon startup. Should be between minPoolSize and maxPoolSize 

连接池初始化时获取的链接数,介于minPoolSize和maxPoolSize之间 


minPoolSize: 

Minimum number of Connections a pool will maintain at any given time. 

最小链接数 


maxPoolSize: 

Maximum number of Connections a pool will maintain at any given time. 

最大连接数 


acquireIncrement: 

Determines how many connections at a time c3p0 will try to acquire when the pool is exhausted. 

在当前连接数耗尽的时候,一次获取的新的连接数 


maxIdleTime: 

Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire. 

最大空闲的时间,单位是秒,无用的链接再过时后会被回收 



3:proxool数据库连接池



applicationContext.xml配置


<bean id="dataSource"  

        class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<!-- 数据源类采用JDBC数据源 -->  

    <property name="driverClassName">

    <!-- 将数据库连接交给了proxool管理,使它的驱动 --> 

         <value>org.logicalcobwebs.proxool.ProxoolDriver</value>  

    </property>  

    <property name="url">  

    <!-- 数据库连接池的别名,与proxool.xml中的Alias必须一致 -->  

         <value>proxool.myDataSource</value>  

    </property>  

</bean> 



2、Proxool.xml配置

<?xml version="1.0" encoding="UTF-8"?>

<something-else-entirely>

  <proxool>

    <alias>myDataSource</alias>

    <driver-url>

        jdbc:sqlserver://localhost:1433;databaseName=VellMemberCenter

       </driver-url>

    <driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>

    <driver-properties>

      <property name="user" value="sa"/>

      <property name="password" value="test"/>

    </driver-properties>

    <!-- 保留线程处于睡眠状态的最长时间 -->

    <house-keeping-sleep-time>1000</house-keeping-sleep-time> 

    <!-- 没有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受-->

    <maximum-new-connections>20</maximum-new-connections>

    <!-- 连接池中可用的连接数量.如果当前的连接池中的连接少于这个数值.新的连接将被建立 -->

  <prototype-count>2</prototype-count>


    <!-- 最大的数据库连接数. -->

    <maximum-connection-count>1000</maximum-connection-count>

    <!-- 最小的数据库连接数 -->

  <minimum-connection-count>1</minimum-connection-count>

    <!--  <maximum-active-time>60000</maximum-active-time>-->


    <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>

  </proxool>

</something-else-entirely>





Web.xml配置



<!--proxool start -->

 <servlet>  

        <servlet-name>proxoolServletConfigurator</servlet-name>  

        <servlet-class>  

            org.logicalcobwebs.proxool.configuration.ServletConfigurator   

        </servlet-class>  

        <init-param>  

            <param-name>xmlFile</param-name>  


<!--这个路径是自己的文件所在路径,一般和spring的applicationContext是同一个目录-->

            <param-value>/WEB-INF/config/Proxool.xml</param-value>  

        </init-param>  

                  <!-- 由于proxool要先加载,所以启动优先级要比spring高,否则在spring加载时会报错 -->  

        <load-on-startup>1</load-on-startup>  

    </servlet>  

<!-- proxool end -->


<!-- 这里是为了监视连接池的状态 wjhlangzi-->

<servlet>

  <servlet-name>proxool</servlet-name>

  <servlet-class>

    org.logicalcobwebs.proxool.admin.servlet.AdminServlet

  </servlet-class>

  </servlet>

  <servlet-mapping>

  <servlet-name>proxool</servlet-name>

  <!--这个路径呢,由自己设置即可-->

  <url-pattern>/admin</url-pattern>

  </servlet-mapping>

  <!-- 监视连接池的状态结束 -->



 <!-- 配置受保护域,只有Tomcat管理员才能察看连接池的信息 -->   


    <security-constraint>   


        <web-resource-collection>   


            <web-resource-name>proxool</web-resource-name>   


            <url-pattern>/admin</url-pattern>   


        </web-resource-collection>   


        <auth-constraint>   


            <role-name>manager</role-name>   


        </auth-constraint>   


    </security-constraint>   


    <login-config>   


        <auth-method>BASIC</auth-method>   


        <realm-name>proxool manager Application</realm-name>   


    </login-config>   


    <security-role>   


        <description>   


            The role that is required to log in to the Manager   


            Application   


        </description>   


        <role-name>manager</role-name>   


    </security-role> 



如果上面的配置有异常

如果有异常:org.logicalcobwebs.proxool.ProxoolException: Attempt to refer to a unregistered pool by its alias 'myDataSource'


监听器:

/**

 * 

 */

package com.vellsoft.pms.listener;

import java.io.File;   

import java.util.Enumeration;   

import java.util.Properties;   


import javax.servlet.ServletContext;   

import javax.servlet.ServletContextEvent;   

import javax.servlet.ServletContextListener;   


import org.apache.commons.logging.Log;   

import org.apache.commons.logging.LogFactory;   

import org.logicalcobwebs.proxool.ProxoolException;   

import org.logicalcobwebs.proxool.configuration.JAXPConfigurator;   

import org.logicalcobwebs.proxool.configuration.PropertyConfigurator;


/**

 * @author Administrator

 *

 */

public class ProxoolListener implements ServletContextListener{

private static final Log LOG = LogFactory.getLog(ProxoolListener.class);   


    private static final String XML_FILE_PROPERTY = "xmlFile";   


    private static final String PROPERTY_FILE_PROPERTY = "propertyFile";   


    private static final String AUTO_SHUTDOWN_PROPERTY = "autoShutdown";   


    @SuppressWarnings("unused")   

    private boolean autoShutdown = true;   


    public void contextDestroyed(ServletContextEvent arg0)   

    {   

        System.out.println("destroy database pool....");   

    }   


    public void contextInitialized(ServletContextEvent contextEvent)   

    {   

        ServletContext context = contextEvent.getServletContext(); //对应servlet的init方法中ServletConfig.getServletContext()   

        String appDir = contextEvent.getServletContext().getRealPath("/");   

        Properties properties = new Properties();   


        Enumeration names = context.getInitParameterNames();   

        while (names.hasMoreElements()) {   

            String name = (String) names.nextElement();   

            String value = context.getInitParameter(name);   


            if (name.equals(XML_FILE_PROPERTY)) {   

                try {   

                    File file = new File(value);   

                    if (file.isAbsolute()) {   

                        JAXPConfigurator.configure(value, false);   

                    } else {   

                        JAXPConfigurator.configure(appDir + File.separator + value, false);   

                    }   

                } catch (ProxoolException e) {   

                    LOG.error("Problem configuring " + value, e);   

                }   

            } else if (name.equals(PROPERTY_FILE_PROPERTY)) {   

                try {   

                    File file = new File(value);   

                    if (file.isAbsolute()) {   

                        PropertyConfigurator.configure(value);   

                    } else {   

                        PropertyConfigurator.configure(appDir + File.separator + value);   

                    }   

                } catch (ProxoolException e) {   

                    LOG.error("Problem configuring " + value, e);   

                }   

            } else if (name.equals(AUTO_SHUTDOWN_PROPERTY)) {   

                autoShutdown = Boolean.valueOf(value).booleanValue();   

            } else if (name.startsWith("jdbc")) { //此处以前是PropertyConfigurator.PREFIX改为jdbc   

                properties.setProperty(name, value);   

            }   

        }   


        if (properties.size() > 0) {   

            try {   

                PropertyConfigurator.configure(properties);   

            } catch (ProxoolException e) {   

                LOG.error("Problem configuring using init properties", e);   

            }   

        }   

    }   


}


Web.xml配置



  <context-param>   

    <param-name>xmlFile</param-name>   

    <param-value>WEB-INF/Proxool.xml</param-value>   

  </context-param>

  <listener>   

    <!-- 位置在spring的监听器之前-->

<listener-class>com.vellsoft.pms.listener.ProxoolListener</listener-class>   

</listener> 

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<!-- 这里是为了监视连接池的状态 wjhlangzi-->

<servlet>

  <servlet-name>proxool</servlet-name>

  <servlet-class>

    org.logicalcobwebs.proxool.admin.servlet.AdminServlet

  </servlet-class>

  </servlet>

  <servlet-mapping>

  <servlet-name>proxool</servlet-name>

  <!--这个路径呢,由自己设置即可-->

  <url-pattern>/admin</url-pattern>

  </servlet-mapping>

  <!-- 监视连接池的状态结束 -->



 <!-- 配置受保护域,只有Tomcat管理员才能察看连接池的信息 -->   


    <security-constraint>   


        <web-resource-collection>   


            <web-resource-name>proxool</web-resource-name>   


            <url-pattern>/admin</url-pattern>   


        </web-resource-collection>   


        <auth-constraint>   


            <role-name>manager</role-name>   


        </auth-constraint>   


    </security-constraint>   


    <login-config>   


        <auth-method>BASIC</auth-method>   


        <realm-name>proxool manager Application</realm-name>   


    </login-config>   


    <security-role>   


        <description>   


            The role that is required to log in to the Manager   


            Application   


        </description>   


        <role-name>manager</role-name>   


    </security-role> 



另外一种配置:


<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">

org.hibernate.dialect.SQLServerDialect

</prop>

<prop key="hibernate.show_sql">true</prop>

<prop key="hibernate.format_sql">true</prop>

<prop key="hibernate.cache.use_query_cache">true</prop>

<prop key="hibernate.cache.use_second_level_cache">

true

</prop>

<prop key="hibernate.cache.provider_class">

org.hibernate.cache.EhCacheProvider

</prop>

<prop key="hiberante.format_sql">true</prop>

<prop key="hibernate.proxool.pool_alias">myDataSource</prop>

   <prop key="hibernate.proxool.xml">proxool.xml</prop>

   <prop key="hibernate.connection.provider_class">

    org.hibernate.connection.ProxoolConnectionProvider

   </prop>

</props>

</property>

<property name="mappingLocations">

<value>classpath:cc/smh/bean/*.hbm.xml</value>

</property>

</bean>

proxool.xml是在classpath   src下放着的




 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics