【发布时间】:2010-01-05 17:13:24
【问题描述】:
如果我在 hibernate.cfg.xml 文件中输入了错误的连接 URL,我希望能够检测到它并优雅地终止,但我不知道怎么做;它只是在休眠初始化过程中无限期地挂在 buildSessionFactory() 上:
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
它在一个 try 块中,我试图捕获一个通用异常,但 buildSessionFactory() 从来没有抛出一个,它只是挂起。这是我的 hibernate.cfg.xml 中的 URL 元素:
<property name="hibernate.connection.url">jdbc:mysql://123.123.123.123/mydb</property>
我的系统:Ubuntu 9.10 和 Tomcat 5.5、Java 1.6、Hibernate 3 和 MySQL 5。
当我第一次初始化休眠时,它只挂起 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>
【问题讨论】:
-
您看到的延迟很可能是由 c3p0 的 acquireRetryDelay 和 acquireRetryAttempts 属性引起的,它们会在暂停一小段时间(默认为 1 秒)后重试连接。总的来说,花很多精力让你的应用处理简单的配置错误似乎很愚蠢(除非你的设置有什么我不明白的地方)。
-
感谢您的回复。请参阅我对 Pascal 答案的评论。
标签: java mysql hibernate url connection