我在我的java应用程序中使用spring + hibernate + tomcat jdbc。我希望能够处理连接问题,例如,发生数据库崩溃时。我得到的问题是hibernate阻止尝试获取jdbc连接(例如,当mysql关闭时)并且永远不会超时使http请求无限期挂起。
这是我的hibernate配置:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>detection/model/conf/rules.hbm.xml</value>
</list>
</property>
</bean>
我的jdbc数据源配置:
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="initialSize" value="10" />
<property name="maxActive" value="100" />
<property name="maxIdle" value="50" />
<property name="minIdle" value="10" />
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="maxWait" value="2000"/>
<property name="validationQuery" value="/*ping*/ SELECT 1"/>
<property name="timeBetweenEvictionRunsMillis" value="2000"/>
<property name="removeAbandonedTimeout" value="2000"/>
<property name="removeAbandoned" value="true"/>
<property name="validationInterval" value="5000"/>
</bean>
有没有办法告诉hibernate在一段时间后等待连接超时?
更新:
我切换到c3p0,但我有相同的行为,但我得到了更多与c3p0调试信息。我可以看到抛出一个异常,但是c3p0似乎抓住它并且什么都不做,所以http请求仍然挂起,直到我重新启动mysql服务器。
DEBUG 2012-12-07 09:07:46,994 : Opening Hibernate Session
DEBUG 2012-12-07 09:07:46,994 : opened session at timestamp: 13548892669
DEBUG 2012-12-07 09:07:46,994 : about to open PreparedStatement (open PreparedStatements: 0, globally: 2)
DEBUG 2012-12-07 09:07:46,994 : opening JDBC connection
DEBUG 2012-12-07 09:07:46,994 : trace com.mchange.v2.resourcepool.BasicResourcePool@195b6aad [managed: 10, unused: 7, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@6b0ede6)
DEBUG 2012-12-07 09:07:46,994 : select rules0_.product as product2_, rules0_.rules as rules2_, rules0_.type as type2_ from rules rules0_ where rules0_.product=? and rules0_.type=?
DEBUG 2012-12-07 09:07:46,995 : com.mchange.v2.c3p0.impl.NewPooledConnection@60487c5f handling a throwable.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
答案 0 :(得分:1)
终于通过c3p0得到了我想要的行为。这是我使用的配置:
<property name="acquireRetryDelay" value="5000"/>
<property name="breakAfterAcquireFailure" value="true"/>
<property name="checkoutTimeout" value="1"/>
<property name="testConnectionOnCheckin" value="1" />
我认为关键属性是breakAfterAcquireFailure,它将正确地从池中删除断开的连接,而idleCheck测试不关闭连接并在数据库关闭时无限期挂起。这使得checkoutTimeout正常工作,因为池已正确管理。连接提供程序也会在数据库重新连接时正确地重新连接。
答案 1 :(得分:0)
此SO Post描述了在无法获取Connection时如何配置C3PO以引发异常。