代码之家  ›  专栏  ›  技术社区  ›  yelliver

配置单元JDBC-getConnection失败时连接泄漏

  •  0
  • yelliver  · 技术社区  · 6 年前

    https://www.cloudera.com/downloads/connectors/hive/jdbc/2-6-2.html

    有时,当调用getConnection()失败时(并不总是,取决于服务器的稳定性),它会显示以下异常:

    MyDAO - Cannot create connection from DataSource@21f421b8 
    at com.cloudera.hiveserver2.hivecommon.api.HS2Client.closeSession(Unknown Source)
    at com.cloudera.hiveserver2.hivecommon.core.HiveJDBCCommonConnection.establishConnection(Unknown Source)
    at com.cloudera.hiveserver2.jdbc.core.LoginTimeoutConnection.connect(Unknown Source)
    at com.cloudera.hiveserver2.jdbc.common.BaseConnectionFactory.doConnect(Unknown Source)
    at com.cloudera.hiveserver2.jdbc.common.AbstractDataSource.getSimbaConnection(Unknown Source)
    at com.cloudera.hiveserver2.jdbc.common.AbstractDataSource.getConnection(Unknown Source)
    

    当我用netstat命令检查时:

    netstat -an --tcp --program
    

    问题是:

    1. 为什么当我调用getConnection()时,会调用closeSession()?
    2. 是因为closeSession()失败,无法释放tcp连接吗?是否认为是连接泄漏?
    0 回复  |  直到 6 年前
        1
  •  0
  •   yelliver    6 年前

    我反编译了驱动程序,检查H2SClient类:

    public void closeSession() throws ErrorException {
        if (this.m_hasOpenSession) {
            try {
                TCloseSessionReq var1 = new TCloseSessionReq();
                var1.setSessionHandle(this.m_openSessionResp.getSessionHandle());
                this.m_client.CloseSession(var1);
                if (null != this.m_client && null != this.m_client.getInputProtocol() && null != this.m_client.getInputProtocol().getTransport()) {
                    this.m_client.getInputProtocol().getTransport().close(); //line 8
                }
    
                this.m_hasOpenSession = false;
            } catch (Exception var3) {
                ErrorException var2 = HiveJDBCCommonDriver.s_HiveMessages.createGeneralException(HiveJDBCMessageKey.CONN_SESSION_ERR.name(), "Close Session Error");
                var2.initCause(var3);
                throw var2;
            }
        }
    
    }
    

    在catch块或finally块中也应调用该关闭:

    public void closeSession() throws ErrorException {
        if (this.m_hasOpenSession) {
            try {
                TCloseSessionReq var1 = new TCloseSessionReq();
                var1.setSessionHandle(this.m_openSessionResp.getSessionHandle());
                this.m_client.CloseSession(var1);
    
                var2.initCause(var3);
                throw var2;
            } finally {
                if (null != this.m_client && null != this.m_client.getInputProtocol() && null != this.m_client.getInputProtocol().getTransport()) {
                    this.m_client.getInputProtocol().getTransport().close(); //line 8
                }   
            }
        }
    }
    
    推荐文章