dbcp:
driverClassName
url
username
password
上面四个分别是驱动,连接字符串,用户名和密码
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.OracleDriver
jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:DBSERVER
jdbc.username=user
jdbc.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.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.1.1:1521:shili
jdbc.username=myname
jdbc.password=111
jdbc.maxActive=5
jdbc.maxIdle=5
jdbc.minIdle=5
jdbc.initialSize=5
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.numTestsPerEvictionRun=5
jdbc.minEvictableIdleTimeMillis=30000
jpa.database=ORACLE
jpa.showSql=false
jpa.generateDdl=false
jdbc.getdate.sql=select sysdate from dual (注意mysql数据库validationQuery这里的值是:select 1)
参数 默认值 描述
validationQuery SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定,
则查询必须是一个SQL SELECT并且必须返回至少一行记录
testOnBorrow true 指明是否在从池中取出连接前进行检验,如果检验失败,
则从池中去除连接并尝试取出另一个.
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
http://www.blogjava.net/wangxinsh55/archive/2011/04/14/348277.html
validationQuery 说明
还有几个很重要的属性,_testOnBorrow、_testOnReturn、_testWhileIdle,这些属性的意义是取得、返回对象和空闲时是否进行验证,检查对象是否有效,默认都为false即不验证。所以当使用DBCP时,数据库连接因为某种原因断掉后,再从连接池中取得连接又不进行验证,这时取得的连接实际已经时无效的数据库连接了。网上很多说DBCP的bug应该都是如此吧,只有把这些属性设为true,再提供_validationQuery语句就可以保证数据库连接始终有效了,
http://blog.csdn.net/sandyen/article/details/723635
http://fine36.blog.163.com/blog/static/189251005201182144143661/
c3p0:
driverClass
jdbcUrl
user
password
minPoolSize
maxPoolSize
initialPoolSize
acquireIncrement 池中没有空闲连接时,一次请求获取的连接数
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方法)
<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时采用如下定义:
xml 代码
<Context path="/livsorder" docBase="/home/httpd/html/livsorder"
defaultSessionTimeOut="3600" isWARExpanded="true"
isWARValidated="false" isInvokerEnabled="true"
isWorkDirPersistent="false"/>
3600秒=1小时
2. 在web.xml中通过参数指定:
xml 代码
<session-config>
<session-timeout>30</session-timeout>
</session-config>
其中30表示30分钟
3. 在程序中通过servlet api直接修改
java 代码
HttpSession ses = request.getSession();
ses.setMaxInactiveInterval(10);