【问题标题】:Catching UnknownHostException in JDBC class在 JDBC 类中捕获 UnknownHostException
【发布时间】:2017-08-17 18:07:21
【问题描述】:

我正在使用 JDBC 和 c3p0 将 Swing 应用程序连接到 PostgreSQL 数据库。当连接失效时,它会不受控制地引发几个 PSQLException 和 UnknownHostException,这是意料之中的。

ago 17, 2017 5:39:25 PM org.postgresql.Driver connect
GRAVE: Connection error: 
org.postgresql.util.PSQLException: El intento de conexión falló.
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:275)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:194)
    at org.postgresql.Driver.makeConnection(Driver.java:450)
    at org.postgresql.Driver.connect(Driver.java:252)
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:175)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:220)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:206)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:203)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1138)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1125)
    at com.mchange.v2.resourcepool.BasicResourcePool.access$700(BasicResourcePool.java:44)
    at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1870)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)
Caused by: java.net.UnknownHostException: academico.ulasalle.edu.pe
    at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at org.postgresql.core.PGStream.<init>(PGStream.java:68)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:144)
    ... 13 more

我想立即捕获那些 UnknownHostExceptions,这样它们就不会弄乱应用程序的可用性。

我应该在哪里以及如何捕获那些 UnknownHostException?我已经尝试了所有方法,但没有任何效果。

这是我的 BDConnection 类:

public class BDConnection {
    private String m_cc;
    private String m_Driver;
    public Statement statement;
    public Connection conn;     
    ComboPooledDataSource m_Conexion;

    public BDConnection() throws SQLException, ClassNotFoundException {
        m_Driver = "org.postgresql.Driver";
        m_cc = "jdbc:postgresql://myserver.com/mydb";
        open();
    }

    public ComboPooledDataSource GetConexion() {
        return m_Conexion;
    }

    public void open() throws ClassNotFoundException, SQLException {
        try {
            if (m_Conexion == null) {
                m_Conexion = new ComboPooledDataSource();
                m_Conexion.setDriverClass( m_Driver ); 
                m_Conexion.setJdbcUrl( m_cc );
                m_Conexion.setUser("user"); 
                m_Conexion.setPassword("password");     
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public boolean isOpen() throws SQLException {
        return (m_Conexion != null);
    }

    public void close() throws SQLException {
        if (isOpen()) {
            conn.close();
        }
    }

    public ResultSet RS_Query(String SQL){
        try {
            conn = m_Conexion.getConnection();
            conn.setAutoCommit(false);
            statement = conn.createStatement();
            ResultSet result = statement.executeQuery(SQL); 
            conn.commit();
            return result;
        } catch (final SQLException e) {
            e.printStackTrace();
        } finally {
            m_Conexion.close();
        }
        return null;
    }

    public void RS_Update(String SQL){
        try {
            conn = m_Conexion.getConnection();
            conn.setAutoCommit(false);
            statement = conn.createStatement();
            statement.executeUpdate(SQL);
            conn.commit();
        } catch (final SQLException e) {
            e.printStackTrace();
        } finally {
            m_Conexion.close();
        }   
    }
}

【问题讨论】:

  • 你好,在看具体问题之前,这个类有一堆问题。看起来您在每次查询后关闭()连接池,这不是很好。连接池应该是长期存在的;只有连接应该在查询结束时关闭。应该在 finally 块中关闭的是连接,而不是连接池(或者更好的是,使用 try-with-resources 和连接作为资源。
  • 非常感谢,我正在更改它。

标签: java postgresql jdbc exception-handling c3p0


【解决方案1】:

马上澄清一下:UnknownHostException 不是直接抛出的,而是(可能间接地)包裹在一些 SQLException 中。

我想你得到了由

捕获的包装异常
} catch (final SQLException e) {
    e.printStackTrace();
} finally {

在您的 RS_Query() 方法中。

一种策略是捕获包装 UnknownHostException 的异常,将其包装在您的自定义运行时异常中,并允许它飞到您可以捕获它并显示错误窗口(或非阻塞弹出)

} catch (final SQLException e) {
    if (causedByUnknownHostException(e)) {
        throw new RuntimeUnknownHostException(e);
    } else {
        // processing somehow an exception which is not caused by UnknownHostException
        e.printStackTrace();
    }
} finally {

RuntimeUnknownHostException 扩展 RuntimeException

然后在你的全局 UI 异常处理程序中处理它:

try {
    // some code calling conn.RS_Query(...);
} catch (RuntimeUnknownHostException e) {
    ... display the error message
}

检测代码:

private boolean causedByUnknownHostException(Throwable t) {
    if (t == null) {
        return false;
    }
    if (t instanceof UnknownHostException) {
        return true;
    }
    return causedByUnknownHostException(t.getCause());
}

为什么不检查异常(扩展RuntimeException)?这将避免在所有中间方法中声明它的负担,因此它可以到达您的集中式 UI 异常处理程序。

【讨论】:

  • 我试过了,但那里没有发现异常。此外,当我尝试在那里捕获 UnknownHostException 时,该块被指示为无法访问,因为该异常永远不会从“try”块内抛出。
  • 对不起,我错了,当然UnknownHostException 不扩展SQLException,但在你的情况下,它是由SQLException 的子类包装的。根据this更新答案。
猜你喜欢
  • 1970-01-01
  • 2017-05-02
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
  • 2013-02-23
  • 2017-12-22
  • 2018-02-19
  • 2010-12-31
相关资源
最近更新 更多