java - 捕获无效 hibernate 连接 URL 错误

标签 java mysql hibernate url connection

如果我在 hibernate.cfg.xml 文件中放置了错误的连接 URL,我希望能够检测到它并优雅地终止,但我不知道该怎么做;它只是在 hibernate 初始化过程中无限期地卡在 buildSessionFactory() 上:

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

它在一个 try block 中,我试图捕获一个通用异常,但 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>

最佳答案

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

When a c3p0 DataSource attempts and fails to acquire a Connection, it will retry up to acquireRetryAttempts times, with a delay of acquireRetryDelay between each attempt. If all attempts fail, any clients waiting for Connections from the DataSource will see an Exception, indicating that a Connection could not be acquired. Note that clients do not see any Exception until a full round of attempts fail, which may be some time after the initial Connection attempt. If acquireRetryAttempts is set to 0, c3p0 will attempt to acquire new Connections indefinitely, and calls to getConnection() may block indefinitely waiting for a successful acquisition.

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

也许您可以使用较低的值。或者,也许您可​​以只使用正确的 URL 并停止在异常情况(配置错误)上花费时间。

关于java - 捕获无效 hibernate 连接 URL 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2007749/

相关文章:

java - 错误请求 400

java - Spring 中的事务方法

java - 从 Java 中的 Camel 路线获取可视化文档?

java - JDBCTemplate 给出空指针异常?

java - 如何正确删除Android中按钮周围的填充(或边距?)?

mysql - SQL语句问题-如何从2个链接表中检索数据

mysql - 为什么我的 object.save 在一个地方工作而在另一个地方失败?

java - 从无状态 Bean 获取 JDBC Connection 对象

java - 如何在 IntelliJ 中查看 JDK 中的特定 Java 源代码文件?

Java - If语句逻辑错误