在用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>