当无法到达主机时,c3p0不会超时

时间:2015-03-16 18:36:49

标签: java sql-server hibernate jpa c3p0

我的程序在打开时做的第一件事就是尝试在数据库中连接,如果c3p0不会连接它冻结并且不会引发任何错误消息。

奇怪的是,使用 MySql 我得到java.net.UnknownHostException,但是 SqlServer 没有,它会一直尝试。

我想抓住错误并做点什么。我尝试设置这个属性,但没有运气。

<property name="hibernate.c3p0.timeout" value="60"/>
<property name="hibernate.c3p0.unreturnedConnectionTimeout" value="60"/>

我的persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="default" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>com.lala.Something</class>
        <shared-cache-mode>NONE</shared-cache-mode>
        <properties>
            <!-- connection -->
            <property name="javax.persistence.jdbc.url" value="jdbc:sqlserver://localhost\\\\SQLEXPRESS:1433;databaseName=str"/>
            <property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
            <property name="javax.persistence.jdbc.user" value="teste"/>
            <property name="javax.persistence.jdbc.password" value="teste"/>
            <!-- hibernate -->
            <property name="hibernate.format_sql" value="false"/>
            <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.use_sql_comments" value="false"/>
            <!-- c3p0 -->
            <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
            <property name="hibernate.c3p0.min_size" value="1"/>
        </properties>
    </persistence-unit>
</persistence>

3 个答案:

答案 0 :(得分:2)

我决定添加这两个属性:

<强> acquireRetryAttempts

定义c3p0在放弃之前尝试从数据库获取新连接的次数。如果此值小于或等于零,则c3p0将继续尝试无限期地获取连接。

<强> breakAfterAcquireFailure

如果为true,则在使acquireRetryAttempts获取Connection之后,如果无法从数据库获取Connection,则池化的DataSource将声明自身已损坏并永久关闭。如果为false,则无法获取Connection将导致等待池的所有线程获取Connection以抛出异常,但DataSource将保持有效,并将在调用getConnection()后再次尝试获取。

        <property name="hibernate.c3p0.acquireRetryAttempts" value="3"/>
        <property name="hibernate.c3p0.breakAfterAcquireFailure" value="true"/>

答案 1 :(得分:0)

如果c3p0尝试从数据库中获取Connections,那么这些获取尝试就会挂起&#34; - 他们既没有成功也没有失败的例外 - 这很糟糕。悬挂式获取最终将使线程池饱和,迫使它声明为APPARENT DEADLOCK并重建自己。

您尝试设置的两个属性都与此问题无关。如果您想解决这些问题,请查看的c3p0配置属性为maxAdministrativeTaskTime

答案 2 :(得分:0)

虽然被接受有助于减少尝试“获取”从30(!)到3的连接的次数,但是如果服务器没有响应,则getConnection()仍会“挂起”多年。似乎c3p0使用“check out / in”的不同术语来将连接添加到池中。因此,将checkoutTimeout设置为0以外的其他值(等待永远!)解决问题。

我猜测acquireRetryAttempts和checkoutTimeout并应用于每个intialPoolSize连接。