捕获无效的hibernate连接URL错误

时间:2010-01-05 17:13:24

标签: java mysql hibernate url connection

如果我在我的hibernate.cfg.xml文件中输入了错误的连接URL,我希望能够检测到它并优雅地终止,但我无法弄清楚如何;它只是在hibernate初始化过程中无限期地挂起在buildSessionFactory()上:

SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();

它在try块中,我正在尝试捕获一个通用的Exception,但buildSessionFactory()从不抛出一个,它只是挂起。这是我的hibernate.cfg.xml中的URL元素:

<property name="hibernate.connection.url">jdbc:mysql://123.123.123.123/mydb</property>

我的系统:带有Tomcat 5.5,Java 1.6,Hibernate 3和MySQL 5的Ubuntu 9.10。

当我第一次初始化hibernate时,它只挂起22秒,然后开始吐出关于线程和死锁的警告(从这开始):

15:16:25,758  WARN ThreadPoolAsynchronousRunner.class: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@a010ba -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
15:16:25,761  WARN ThreadPoolAsynchronousRunner.class: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@a010ba -- APPARENT DEADLOCK!!! Complete Status: 
Managed Threads: 3
Active Threads: 3
Active Tasks: 
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@109da93 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@1ed1dbe (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@3bc1a1 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
Pending Tasks: 
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@12549c4
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@10df4e2
Pool thread stack traces:
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
    java.net.PlainSocketImpl.socketConnect(Native Method)
    java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    java.net.Socket.connect(Socket.java:525)
    java.net.Socket.connect(Socket.java:475)
    java.net.Socket.<init>(Socket.java:372)
    java.net.Socket.<init>(Socket.java:215)
    com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:253)
    com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:284)
    com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2194)
    com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:723)
    com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
    com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302)
    com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282)
    com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:135)
    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)
    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)
    com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
    com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
    com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

编辑:这是我的hibernate.cfg.xml

中的c3p0属性
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">100</property>
<property name="hibernate.c3p0.max_size">100</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.timeout">100</property>

1 个答案:

答案 0 :(得分:0)

正如BryanD在评论中提到的那样,buildSessionFactory()并没有真正挂起,时间很可能花在试图重新连接的c3p0上。引用c3p0 documentation

  

当c3p0数据源尝试并且无法获取连接时,它将重试最多acquireRetryAttempts次,每次尝试之间的延迟为acquireRetryDelay。如果所有尝试都失败,则从DataSource等待Connections的任何客户端都将看到异常,指示无法获取Connection。请注意,在完整的尝试失败之前,客户端看不到任何异常,这可能是在初始连接尝试之后的某个时间。如果acquireRetryAttempts设置为0,则c3p0将尝试无限期地获取新的Connections,并且对getConnection()的调用可能会无限期地阻止等待成功获取。

如果您没有配置它,acquireRetryAttempts的默认值为30,因此buildSessionFactory()可能确实需要一些时间才能返回。但是,除非你使用的值小于或等于零,否则c3p0将继续尝试无限期地获取一个连接,它会。

也许您可以使用较低的值。或者也许您可以使用正确的URL并停止在特殊情况下花费时间(配置错误)。