hibernate、spring、c3p0整合(连接池)

问题场景

在用hibernate连接oracle10g时log中有如下情况出现:

2015-12-17 20:49:13.699:[DEBUG] Obtaining JDBC connection
2015-12-17 20:49:25.413:[DEBUG] Obtained JDBC connection

可见是连接数据库时获取connection耗时较长,问题的根出在了hibernate的连接池性能满足不了要求,hibernate默认的hibernate.connection.pool_size为1,当然若是以为是此值太小就错了,真正的问题是hibernate默认的连接池性能就是不行,如官方文档所述:

Hibernate's internal connection pooling algorithm is rudimentary, and is provided for development and testing purposes. Use a third-party pool for best performance and stability. To use a third-party pool, replace the hibernate.connection.pool_size property with settings specific to your connection pool of choice. This disables Hibernate's internal connection pool. 

解决方法

使用第三方的连接池,如c3p0.
以下为c3p0的配置样例:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">  
        <property name="driverClass" value="oracle.jdbc.driver.OracleDriver">  
        property>  
        <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:ORCL">property>  
        <property name="user" value="HIBERNATE" />  
        <property name="password" value="HIBERNATE" />  

          
        <property name="minPoolSize" value="10" />
        
        <property name="maxPoolSize" value="100" />  
        
        <property name="maxIdleTime" value="1800" />  
        
        <property name="acquireIncrement" value="3" />  
        
        <property name="maxStatements" value="100" />  
        
        <property name="initialPoolSize" value="10" />  
        
        <property name="idleConnectionTestPeriod" value="60" />  
         
        <property name="acquireRetryAttempts" value="30" />  
         
        <property name="breakAfterAcquireFailure" value="true" />  
        
        <property name="testConnectionOnCheckout" value="false" />  
    bean>  

以下为参考来源

参考url:http://www.cnblogs.com/xinzehome/p/3721678.html
参考内容如下:

数据源的配置
Spring默认数据源:DriverManagerDataSource

DBCP数据源:BasicDataSource、使用jdbc.properties

C3P0数据源:ComboPooledDataSource

BoneCP数据源:

需要的jar包

l   bonecp-0.6.5.jar

l   google-collections-1.0.jar

l   slf4j-api-1.5.11.jar

l   slf4j-log4j12-1.5.11.jar

l   log4j-1.2.15.jar

1. Spring默认数据源:DriverManagerDataSource

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName"><value>${jdbc.driverClassName}value>property>
   <property name="url"><value>${jdbc.url}value>property>
   <property name="username"><value>${jdbc.username}value>property>
   <property name="password"><value>${jdbc.password}value>property>
bean>

2. DBCP数据源:BasicDataSource、使用jdbc.properties

<bean id="dataSource"

  class="org.apache.commons.dbcp.BasicDataSource">

              <property name="driverClassName"

                     value=" oracle.jdbc.driver.OracleDriver">

              property>

              <property name="url"

                     value=" jdbc:oracle:thin:@localhost:1521:orcl">

              property>

              <property name="username" value=" manage">property>

              <property name="password" value=" manage">property>

       bean>

使用配置文件的格式:

<bean id="config" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

              <property name="locations">

                     <value>classpath:jdbc.propertiesvalue>

              property>

       bean>

       <bean id="dataSource"

              class="org.apache.commons.dbcp.BasicDataSource">

              <property name="driverClassName"

                     value="${jdbc.driver}">

              property>

              <property name="url"

                     value="${jdbc.url}">

              property>

              <property name="username" value="${jdbc.username}">property>

              <property name="password" value="${jdbc.password}">property>

       bean>

其中jdbc.properties中内容如下:

jdbc.driver=oracle.jdbc.driver.OracleDriver

jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl

jdbc.username=manage

jdbc.password=manage

DBCP里的参数说明:

dataSource: 要连接的 datasource (通常我们不会定义在 server.xml) 
defaultAutoCommit: 对于事务是否 autoCommit, 默认值为 true 
defaultReadOnly: 对于数据库是否只能读取, 默认值为 false 
driverClassName:连接数据库所用的 JDBC Driver Class, 
maxActive: 可以从对象池中取出的对象最大个数,为0则表示没有限制,默认为8 
maxIdle: 最大等待连接中的数量,设 0 为没有限制 (对象池中对象最大个数) 
minIdle:对象池中对象最小个数 
maxWait: 最大等待秒数, 单位为 ms, 超过时间会丟出错误信息 
password: 登陆数据库所用的密码 
url: 连接数据库的 URL 
username: 登陆数据库所用的帐号 
validationQuery: 验证连接是否成功, SQL SELECT 指令至少要返回一行 
removeAbandoned: 是否自我中断, 默认是 false 
removeAbandonedTimeout: 几秒后会自我中断, removeAbandoned 必须为 true 
logAbandoned: 是否记录中断事件, 默认为 false 
minEvictableIdleTimeMillis:大于0 ,进行连接空闲时间判断,或为0,对空闲的连接不进行验证;默认30分钟
timeBetweenEvictionRunsMillis:失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程,默认-1 
testOnBorrow:取得对象时是否进行验证,检查对象是否有效,默认为false 
testOnReturn:返回对象时是否进行验证,检查对象是否有效,默认为false 
testWhileIdle:空闲时是否进行验证,检查对象是否有效,默认为false 
Ø 在使用DBCP的时候,如果使用默认值,则数据库连接因为某种原因断掉后,再从连接池中取得连接又不进行验证,这时取得的连接实际上就会是无效的数据库连接。因此为了防止获得的数据库连接失效,在使用的时候最好保证: 
username: 登陆数据库所用的帐号 
validationQuery:SELECT COUNT(*) FROM DUAL 
testOnBorrow、testOnReturn、testWhileIdle:最好都设为true 
minEvictableIdleTimeMillis:大于0 ,进行连接空闲时间判断,或为0,对空闲的连接不进行验证 
timeBetweenEvictionRunsMillis:失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程 
Ø PS:在构造GenericObjectPool [BasicDataSource在其createDataSource () 方法中也会使用GenericObjectPool] 时,会生成一个内嵌类Evictor,实现自Runnable接口。如果timeBetweenEvictionRunsMillis大于0,每过timeBetweenEvictionRunsMillis毫秒Evictor会调用evict()方法,检查对象的闲置时间是否大于 minEvictableIdleTimeMillis毫秒(_minEvictableIdleTimeMillis小于等于0时则忽略,默认为30分钟),是则销毁此对象,否则就激活并校验对象,然后调用ensureMinIdle方法检查确保池中对象个数不小于_minIdle。在调用returnObject方法把对象放回对象池,首先检查该对象是否有效,然后调用PoolableObjectFactory 的passivateObject方法使对象处于非活动状态。再检查对象池中对象个数是否小于maxIdle,是则可以把此对象放回对象池,否则销毁此对象 
Ø 上述特性的可设置性已在代码中验证,具体性能是否能实现有待实际验证



3. C3P0数据源:ComboPooledDataSource

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

   <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />  

   <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:orcl">property>

   <property name="user" value="manage">property>

   <property name="password" value="manage">property>

   

      <property name="minPoolSize">

         <value>10value>

      property>

      

      <property name="maxPoolSize">

         <value>30value>

      property>

      

      <property name="initialPoolSize">

         <value>20value>

      property>

      

      <property name="maxIdleTime">

         <value>60value>

      property>

      

      <property name="acquireIncrement">

         <value>5value>

      property>

      

      <property name="maxStatements">

         <value>0value>

      property>

      

      <property name="idleConnectionTestPeriod">

         <value>60value>

      property>

      

      <property name="acquireRetryAttempts">

         <value>30value>

      property>

      

      <property name="breakAfterAcquireFailure">

         <value>truevalue>

      property>

      

      <property name="testConnectionOnCheckout">

         <value>falsevalue>

      property> 

bean>

C3P0参数设置:

 
<property name="acquireIncrement">3property> 

 
<property name="acquireRetryAttempts">30property> 

 
<property name="acquireRetryDelay">1000property> 

 
<property name="autoCommitOnClose">falseproperty> 

 
<property name="automaticTestTable">Testproperty> 

 
<property name="breakAfterAcquireFailure">falseproperty> 

 
<property name="checkoutTimeout">100property> 

 
<property name="connectionTesterClassName">property> 

 
<property name="factoryClassLocation">nullproperty> 

 
<property name="forceIgnoreUnresolvedTransactions">falseproperty> 

 
<property name="idleConnectionTestPeriod">60property> 

 
<property name="initialPoolSize">3property> 

 
<property name="maxIdleTime">60property> 

 
<property name="maxPoolSize">15property> 

 
<property name="maxStatements">100property> 

 
<property name="maxStatementsPerConnection">property> 

 
<property name="numHelperThreads">3property> 

 
<property name="overrideDefaultUser">rootproperty> 

 
<property name="overrideDefaultPassword">passwordproperty> 

 
<property name="password">property> 

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

 
<property name="propertyCycle">300property> 

 
<property name="testConnectionOnCheckout">falseproperty> 

 
<property name="testConnectionOnCheckin">trueproperty> 

 
<property name="user">rootproperty> 

 
<property name="usesTraditionalReflectiveProxies">falseproperty> 
<property name="automaticTestTable">con_testproperty> 
    <property name="checkoutTimeout">30000property> 
    <property name="idleConnectionTestPeriod">30property> 
    <property name="initialPoolSize">10property> 
    <property name="maxIdleTime">30property> 
    <property name="maxPoolSize">25property> 
    <property name="minPoolSize">10property> 
    <property name="maxStatements">0property> 
    <user-overrides user="swaldman"> 
    user-overrides> 
default-config> 
<named-config name="dumbTestConfig"> 
    <property name="maxStatements">200property> 
    <user-overrides user="poop"> 
      <property name="maxStatements">300property> 
    user-overrides> 
   named-config> 
c3p0-config> 
Ø 上述特性的可设置性已在代码中验证,具体性能是否能实现有待实际验证 
Ø 从配置项的内容来看,C3P0和DBCP都有比较详细的有关连接检测保证的配置,我们可以看到C3P0可以控制数据源内加载的PreparedStatements数量,并且可以设置帮助线程的数量来提升JDBC操作的速度,这些是DBCP未提供的;另外从网络上的评价来看,DBCP出现Bug的频率要大于C3P0,不过这一点有待于我们自己实际的检测。



4. proxool数据源

<!bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
   <property name="driver"><value>${jdbc.driverClassName}value>property>
   <property name="driverUrl"><value>${jdbc.url}value>property>
   <property name="user"><value>${jdbc.username}value>property>
   <property name="password"><value>${jdbc.password}value>property>
   <property name="alias"><value>testvalue>property>
   <property name="houseKeepingSleepTime"><value>90000value>property>
   <property name="prototypeCount"><value>10value>property>
   <property name="maximumConnectionCount"><value>100value>property>
   <property name="minimumConnectionCount"><value>10value>property>
   <property name="trace"><value>truevalue>property>
   <property name="verbose"><value>truevalue>property>
bean>

Ø Proxool的使用和dbcp以及c3p0稍有不同,我们需要并且只需要在使用基本的java.sql.DriverManager之前加载org.logicalcobwebs.proxool.ProxoolDriver驱动类,并且按照proxool定义的url格式 ["proxool." + alias + ":" + driverClass + ":" + driverUrl ,其中alias是为连接池自定义的别名] 来获得connection;具体的可以参看proxool doc下的UserGuide,或本文所附的示例代码。下面对连接池的特性配置作详细说明 [这个是自己翻译的,不一定准确,有问题时请参看doc下的Properties ~]。 
n fatal-sql-exception 
以逗号隔开的异常列表,当设置了此项之后,每当出现SQLException时都将与列表中异常项作比较,如果匹配则认为出现fatal异常,这将导致connection被丢弃,并且不论出现任何情况该异常将被重抛一次以通知用户发生的情况。默认值为null 
n fatal-sql-exception-wrapper-class 
如果配置了fatal-sql-exception,则默认的操作是丢弃引起SQLException的原因而只是抛出原始异常。使用fatal-sql-exception-wrapper-class这个特性可以将SQLException包装到继承SQLException或RunTimeException的任何异常类里。Proxool提供了两个类供使用FatalSQLException和FatalRunTimeException;使用这两个类的话就将该选项设置为'org.logicalcobwebs.proxool.FatalSQLException'或者'org.logicalcobwebs.proxool.FatalRuntimeException'。默认值为null 
n house-keeping-sleep-time 
proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁,默认值为30秒 
n house-keeping-test-sql 
如果侦察线程发现闲置连接,则会使用这个SQL语句来对这些连接进行检查;这项设置的语句应该能够被很快的执行,例如查询当前时间 [info.setProperty("proxool.house-keeping-test-sql", "select CURRENT_DATE");] 。如果不设置则该选项被忽略 
n injectable-connection-interface、injectable-statement-interface、injectable-prepared-statement-interface、injectable-callable-statement-interface 
n jmx 
如果此项设为true,则连接池将被以名称"Proxool:type=Pool, name=<alias>"注册为JMS Server的MBean。默认值为false 
n jmx-agent-id 
当且仅当jmx选项设为true时使用,为以逗号分隔的连接持注册到的JMS代理名称列表;如果不设置则所有注册的JMX Server都将被使用 
n maximum-active-time 
线程最大存活时间,超过此时间的线程将被守护线程kill掉,默认值为5分钟 
n maximum-connection-count 
到数据库的最大连接数,超过了这个连接,再有请求时,就排在队列中等候,最大的等待请求数由simultaneous-build-throttle决定;默认值为15 
n maximum-connection-lifetime 
连接最大存活时间,毫秒为单位,默认值为4小时 
n minimum-connection-count 
不管是否被使用都保持开放的最小连接数,默认值为5 
n overload-without-refusal-lifetime 
用来判断连接池状态,如果在此选项设置时间内(毫秒为单位)拒绝了连接,则认为过负载。默认值为60秒 
n prototype-count 
最少保持的空闲连接数,注意与minimum-connection-count区分。默认值为0 
n simultaneous-build-throttle 
最大的等待请求数,默认值为10 
n test-before-use 
如果设为true则connection在使用前将以house-keeping-test-sql设置的语句测试,如果测试不通过则该connection被丢弃并会重新分配一个connection。默认为false 
n test-after-use 
如果设为true则connection在关闭(放回连接池)前将以house-keeping-test-sql设置的语句测试,如果测试不通过connection将被丢弃。默认值为false 
Ø 与其它连接池特性的设置方法不同,Proxool不提供相应的set方法,所有特性都要以诸如info.setProperty("proxool.jmx", "false");方式设定 
Ø 上述特性的可设置性已在代码中验证,具体性能是否能实现有待实际验证 
Ø Proxool与DBCP以及C3P0的性能比较,网上众说纷纭,有待我们自己的测试



5. BoneCP数据源:

需要的jar包

l   bonecp-0.6.5.jar

l   google-collections-1.0.jar

l   slf4j-api-1.5.11.jar

l   slf4j-log4j12-1.5.11.jar

l   log4j-1.2.15.jar

acquireIncrement: 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 
driveClass:数据库驱动 
jdbcUrl:响应驱动的jdbcUrl 
username:数据库的用户名 
password:数据库的密码 
idleConnectionTestPeriod:检查数据库连接池中控线连接的间隔时间,单位是分,默认值:240,如果要取消则设置为0 
idleMaxAge:连接池中未使用的链接最大存活时间,单位是分,默认值:60,如果要永远存活设置为0 
maxConnectionsPerPartition:每个分区最大的连接数 
minConnectionsPerPartition:每个分区最小的连接数 
partitionCount:分区数,默认值2,最小1,推荐3-4,视应用而定 
acquireIncrement:每次去拿数据库连接的时候一次性要拿几个,默认值:2 
statementsCacheSize:缓存prepared statements的大小,默认值:0 
releaseHelperThreads:每个分区释放链接助理进程的数量,默认值:3,除非你的一个数据库连接的时间内做了很多工作,不然过多的助理进程会影响你的性能



<beanid="mainDataSource"class="com.jolbox.bonecp.BoneCPDataSource"destroy-method="close">

<propertyname="driverClass"value="com.mysql.jdbc.Driver"/>

<propertyname="jdbcUrl"value="jdbc:mysql://127.0.0.1/yourdb"/>

<propertyname="username"value="root"/>

<propertyname="password"value="abcdefgh"/>

<propertyname="idleConnectionTestPeriod"value="60"/>

<propertyname="idleMaxAge"value="240"/>

<propertyname="maxConnectionsPerPartition"value="30"/>

<propertyname="minConnectionsPerPartition"value="10"/>

<propertyname="partitionCount"value="3"/>

<propertyname="acquireIncrement"value="5"/>

<propertyname="statementsCacheSize"value="100"/>

<propertyname="releaseHelperThreads"value="3"/>

bean>



6.JNDI数据源

第一步:Tomcat下conf—Catalina—localhost配置一个xml文件,名字就是项目名



<Context docBase="/D:/spring/man/WebRoot" path="/man">

   <ResourceParams name="vadcms/oracle">

      <parameter>

         <name>factoryname>

         <value>org.apache.commons.dbcp.BasicDataSourceFactoryvalue>

      parameter>

      <parameter>

         <name>driverClassNamename>

         <value>oracle.jdbc.driver.OracleDrivervalue>

      parameter>

      <parameter>

         <name>urlname>

         <value>jdbc:oracle:thin:@localhost:1521:orclvalue>

      parameter>

      <parameter>

         <name>passwordname>

         <value>managevalue>

      parameter>

      <parameter>

         <name>usernamename>

         <value>managevalue>

      parameter>

      <parameter>

         <name>maxWaitname>

         <value>10000value>

      parameter>

      <parameter>

         <name>maxActivename>

         <value>30value>

      parameter>

      <parameter>

         <name>maxIdlename>

         <value>50value>

      parameter>

   ResourceParams>

Context>

vadcms/oracle为数据源的名字

2.在web.xml里加一句话

<resource-ref>

      <res-ref-name> vadcms/oracle res-ref-name>

      <res-type>javax.sql.DataSourceres-type>

      <res-auth>Containerres-auth>

   resource-ref>



3.applicationContext.xml中配置dataSource

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

   <property name="jndiName">

      <value>java:comp/env/ vadcms/oracle value>

   property>

bean>

你可能感兴趣的:(hibernate、spring、c3p0整合(连接池))