DBCP与c3p0__连接池参数详细说明

来源:互联网 发布:苹果5s数据用不了 编辑:程序博客网 时间:2024/05/29 18:58
dbcp:driverClassNameurlusernamepassword

上面四个分别是驱动,连接字符串,用户名和密码

maxActive 连接池支持的最大连接数maxIdle 连接池中最多可空闲maxIdle个连接minIdle 连接池中最少空闲maxIdle个连接initialSize 初始化连接数目maxWait 连接池中连接用完时,新的请求等待时间,毫秒timeBetweenEvictionRunsMillis timeBetweenEvictionRunsMillis和minEvictableIdleTimeMillis一起使用,每timeBetweenEvictionRunsMillis毫秒秒检查一次连接池中空闲的连接,把空闲时间超过minEvictableIdleTimeMillis毫秒的连接断开,直到连接池中的连接数到minIdle为止minEvictableIdleTimeMillis 连接池中连接可空闲的时间,毫秒removeAbandoned true,false,是否清理removeAbandonedTimeout秒没有使用的活动连接,清理后并没有放回连接池removeAbandonedTimeout 活动连接的最大空闲时间logAbandoned true,false,连接池收回空闲的活动连接时是否打印消息minEvictableIdleTimeMillis,removeAbandonedTimeout这两个参数针对的连接对象不一样,minEvictableIdleTimeMillis针对连接池中的连接对象,removeAbandonedTimeout针对未被close的活动连接.

在配置时,主要难以理解的主要有:removeAbandoned 、logAbandoned、removeAbandonedTimeout、maxWait这四个参数,设置了rmoveAbandoned=true那么在getNumActive()快要到getMaxActive()的时候,系统会进行无效的Connection的回收,回收的Connection为removeAbandonedTimeout(默认300秒)中设置的秒数后没有使用的Connection,激活回收机制好像是getNumActive()=getMaxActive()-2。 :)
logAbandoned=true的话,将会在回收事件后,在log中打印出回收Connection的错误信息,包括在哪个地方用了Connection却忘记关闭了,在调试的时候很有用。
在这里私人建议maxWait的时间不要设得太长,maxWait如果设置太长那么客户端会等待很久才激发回收事件。
以下配置的properties文件:

#连接设置jdbc.driverClassName=oracle.jdbc.driver.OracleDriverjdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:DBSERVERjdbc.username=userjdbc.password=pass <!-- 初始化连接 -->dataSource.initialSize=10<!-- 最大空闲连接 -->dataSource.maxIdle=20<!-- 最小空闲连接 -->dataSource.minIdle=5<!-- 最大连接数量 -->dataSource.maxActive=50#是否在自动回收超时连接的时候打印连接的超时错误dataSource.logAbandoned=true#是否自动回收超时连接(这个要看业务需要是否配置,比如执行存储过程或者同步其它部件表,这个需要的时间比较长,所以不能配置该项,默认为,false)dataSource.removeAbandoned=true#超时时间(以秒数为单位)#设置超时时间有一个要注意的地方,超时时间=现在的时间-程序中创建Connection的时间,如果maxActive比较大,比如超过100,那么removeAbandonedTimeout可以设置长一点比如180,也就是三分钟无响应的连接进行回收,当然应用的不同设置长度也不同。dataSource.removeAbandonedTimeout=180#<!-- 超时等待时间以毫秒为单位 -->#maxWait代表当Connection用尽了,多久之后进行回收丢失连接dataSource.maxWait=1000

项目里配置:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><property name="driverClassName"><value>${jdbc.driver}</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><property name="maxActive"><value>${jdbc.maxActive}</value></property><property name="maxIdle"><value>${jdbc.maxIdle}</value></property><property name="minIdle"><value>${jdbc.minIdle}</value></property><property name="initialSize"><value>${jdbc.initialSize}</value></property><!--  <property name="removeAbandonedTimeout"><value>120</value></property><property name="removeAbandoned"><value>true</value></property> --><property name="timeBetweenEvictionRunsMillis"><value>${jdbc.timeBetweenEvictionRunsMillis}</value></property><property name="numTestsPerEvictionRun"><value>${jdbc.numTestsPerEvictionRun}</value></property><property name="minEvictableIdleTimeMillis"><value>${jdbc.minEvictableIdleTimeMillis}</value></property><property name="testOnBorrow" value="true"/><property name="validationQuery" value="${jdbc.getdate.sql}"/>        </bean>
jdbc.driver=oracle.jdbc.driver.OracleDriverjdbc.url=jdbc:oracle:thin:@192.168.1.1:1521:shilijdbc.username=mynamejdbc.password=111jdbc.maxActive=5jdbc.maxIdle=5jdbc.minIdle=5jdbc.initialSize=5jdbc.timeBetweenEvictionRunsMillis=60000jdbc.numTestsPerEvictionRun=5jdbc.minEvictableIdleTimeMillis=30000jpa.database=ORACLEjpa.showSql=falsejpa.generateDdl=falsejdbc.getdate.sql=select sysdate from dual(注意mysql数据库validationQuery这里的值是:select 1)

参数  默认值  描述
validationQuery SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定,则查询必须是一个SQL SELECT并且必须返回至少一行记录。
testOnBorrow true 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个。
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串

validationQuery 说明
还有几个很重要的属性,_testOnBorrow、_testOnReturn、_testWhileIdle,这些属性的意义是取得、返回对象和空闲时是否进行验证,检查对象是否有效,默认都为false即不验证。所以当使用DBCP时,数据库连接因为某种原因断掉后,再从连接池中取得连接又不进行验证,这时取得的连接实际已经时无效的数据库连接了。网上很多说DBCP的bug应该都是如此吧,只有把这些属性设为true,再提供_validationQuery语句就可以保证数据库连接始终有效了。

c3p0:

driverClassjdbcUrluserpasswordminPoolSizemaxPoolSizeinitialPoolSizeacquireIncrement 池中没有空闲连接时,一次请求获取的连接数maxIdleTime 池中连接最大空闲时间acquireRetryAttempts 获取连接失败后,重新尝试的次数acquireRetryDelay 尝试连接间隔时间,毫秒checkoutTimeout 等待连接时间,0为无限等待,毫秒DebugUnreturnedConnectionStackTraces true,false,是否收回未返回的活动连接unreturnedConnectionTimeout 活动连接的时间.

 

总结项目里面的问题:
数据库的连接:
1、读取数据的连接是实时的,如果数据库停了,那么会直接报错,不会自动再次连接或等待连接。
2、如果已经执行查询,那么超时由配置决定(看业务需要)
dataSource.removeAbandoned=true
dataSource.removeAbandonedTimeout=180

数据库的连接和释放是由调用的第三方部件决定
1、spring 提供的org.springframework.jdbc.core.JdbcTemplate会自己调用连接自己释放。(可以查看源代码里面的execute方法)
2、已经声明事务的,由事务管理:
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
 
在方法或者类的上面标识@Transactional。
3、直接使用Hibernate:
使用Hibernate時,大家一般都記住了配置基本的那些選項,比如方言,緩存等,但是有一項配置卻很容易忘掉,這就是連接釋放模式:hibernate.connection.release_mode,可有三個選擇,after_statement/after_transaction/on_close,javadoc中可以看出它們的用處,這裡不再講,注意的一點是,如果不配置的話默認是on_close,那麼如果沒有顯示的去調用session.close或其它關閉連接的方法的話,這個連接是不會被關閉的!在用到連接池的時候,這就更體現出問題了:池中的連接會一直存在著而不會被關閉和回收!
從log4j打印出來的日志也可以看出來,如果是on_close模式,則:
transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
具體的一些細節可以看看hibernate的源代碼,涉及到的兩個類為:
org.hibernate.ConnectionReleaseMode
org.hibernate.jdbc.ConnectionManager
最後,貼一下配置的代碼:
<prop key="hibernate.connection.release_mode">after_transaction</prop>
 

对于应用session超时设置:
前两个都是修改tomcat的配置文件conf
1. 在server.xml中定义context时采用如下定义:

<Context path="/livsorder" docBase="/home/httpd/html/livsorder"defaultSessionTimeOut="3600" isWARExpanded="true"isWARValidated="false" isInvokerEnabled="true"isWorkDirPersistent="false"/>

3600秒=1小时
2. 在web.xml中通过参数指定:

<session-config><session-timeout>30</session-timeout></session-config>

其中30表示30分钟
3. 在程序中通过servlet api直接修改

HttpSession ses = request.getSession();//设置单位为秒,设置为-1永不过期。ses.setMaxInactiveInterval(10);
原创粉丝点击