日期:2014-05-16  浏览次数:20413 次

拣点芝麻:dbcp (Oracle)重新链接的问题 - Cause: java.sql.SQLException: No more data to read from socket

之前用c3p0 做的心跳,这次改成了dbcp做心跳,老是出现这个No more data to read from socket问题(ibatis+spring)。

该异常通常是因为使用了连接池,当从连接池取得的connection失效或者超时的时候,使用这个连接来进行数据库操作就会抛出以上异常。 
解决方法就是让数据库连接池在给你返回connection之前,检查该connnection是否超时或者失效,如果是,则evict这个connection,并返回一个可用的connection。 


具体配置如下

	<bean id="dataSourceSC" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${sc.jdbc.driverClassName}" />
		<property name="url" value="${sc.jdbc.url}" />
		<property name="username" value="${sc.jdbc.username}" />
		<property name="password" value="${sc.jdbc.password}" />
		<property name="initialSize" value="10" />
		<property name="maxActive" value="30" />
		<property name="maxIdle" value="15" />
		<property name="minIdle" value="5" />
		<property name="removeAbandoned" value="true" />
		<property name="removeAbandonedTimeout" value="60" />
		<property name="maxWait" value="10000" />
		<property name="logAbandoned" value="true" />
		<property name="testOnBorrow">
			<value>true</value>
		</property>
		<property name="testOnReturn">
			<value>true</value>
		</property>
		<property name="testWhileIdle">
			<value>true</value>
		</property>
		<property name="minEvictableIdleTimeMillis">
			<value>180000</value>
		</property>
		<property name="timeBetweenEvictionRunsMillis">
			<value>360000</value>
		</property>
		<property name="validationQuery">
			<value>SELECT 1 FROM SYS.DUAL</value>
		</property>
	</bean>

贴一篇对dbcp链接解释比较详细的文章

数据库链接 常见的问题:

1. 数据库意外重启后,原先的数据库连接池能自动废弃老的无用的链接,建立新的数据库链接

2. 网络异常中断后,原先的建立的 tcp 链接,应该能进行自动切换。比如网站演习中的交换机重启会导致网络瞬断

3. 分布式数据库中间件,比如 cobar 会定时的将空闲链接异常关闭,客户端会出现半开的空闲链接。

 

大致思考解决思路:

1.      sql 心跳检查 ( 主动式 )

2.      拿链接尝试一下,发现处理失败丢弃链接,探雷的请求会失败几个  ( 牺牲小我,完成大我的精神 )