2016-04-28 4 views
2

次の警告の理由は何ですか?MySQLのステートメントキャンセルタイマを停止できませんでした

WARNING: The web application [TI] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered. 
Apr 28, 2016 11:03:25 AM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads 
WARNING: The web application [TI] appears to have started a thread named [MySQL Statement Cancellation Timer] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: 
java.lang.Object.wait(Native Method) 
java.lang.Object.wait(Object.java:503) 
java.util.TimerThread.mainLoop(Timer.java:526) 
java.util.TimerThread.run(Timer.java:505) 

コードを変更したときに発生し、tomcatが再起動するたびに発生します。 mysql接続を作成していますが、正しく閉じていると思います。
ここに私のコードです。

@RequestMapping(value = "/file/md5", method = RequestMethod.POST) 
public ResponseEntity<?> md5Status(@RequestParam(required = true) String filename) { 

    Connection con = SqlUtility.getMysqlConnection(host, port, database,username, password); 
    SqlUtility.closeDbInstances(SqlUtility.mysqlConnection); 
    SqlUtility.closeDbInstances(con); 
    return new ResponseEntity<>(HttpStatus.CONFLICT); 
} 

ここにユーティリティコードがあります。

public static Connection mysqlConnection = null; 
private static PreparedStatement preparedStatement = null; 
private static ResultSet resultSet = null; 

public static Connection getMysqlConnection(String host, int port, String database, String username, 
     String password) { 
    MysqlDataSource mds = null; 
    try { 
     if (mysqlConnection == null || mysqlConnection.isClosed()) { 
      if (database != null && host != null) { 
       while (mds == null) { 
        System.out.println("In Loop"); 
        mds = new MysqlDataSource(); 
        mds.setServerName(host); 
        mds.setPortNumber(port); 
        mds.setDatabaseName(database); 
        mds.setUser(username); 
        mds.setPassword(password); 
        try { 
         mysqlConnection = mds.getConnection(); 
        } catch (CommunicationsException e) { 
         System.out.format(
           "Error occurred while trying to get connection with database [%s]. Are your database host [%s] and port [%s] correct? %n%s%n", 
           database, host, port, e); 
         mds = null; 
         // Had to handle for retrying again and again 
         // This is because your mysql is bind on localhost change it in my.cfg 
        } 
       } 
      } else { 
       System.out.format(
         "Error occurred while trying to get connection with database [%s] with username [%s] and password [%s].\n [ATTN] Make sure your DB adapter properties file contains all required attributes. %n", 
         database, username, password); 

      } 

     } 
    } catch (SQLException e) { 
     System.out.format(
       "Error occurred while trying to get connection at host [%s] with database [%s] with username [%s] and password [%s] %n%s%n", 
       host, database, username, password, e); 
     // It might be because of the database privileges which must be grant to access 
    } catch (RuntimeException e) { 
     System.out.format("Error occurred while trying to get [%s] Connection %n%s%n", database, e); 
    } 

    if (mysqlConnection != null) 
     System.out.format("[%S] Connection Successfully Created%n", database); 
    return mysqlConnection; 

} 

public static void closeDbInstances(Connection con) { 
    System.out.println("Trying to close Database Connection..."); 
    if (con != null && preparedStatement != null && resultSet != null) { 
     try { 
      resultSet.close(); 
      preparedStatement.close(); 
      con.close(); 
      System.out.println("Database Connection Closed"); 
     } catch (SQLException e) { 
      System.out.println("Error occurred while trying to close Database connection " + e); 
     } 
    } 
} 
+0

tomcat libにmysql connector jarがありますか? –

+0

いいえ必要ですか? – Root

+0

はい、tomcat libにconnector jarを追加してから試してみてください。 –

答えて

0

(古い質問が、私は同じエラー/警告メッセージが発生した) あなたはQueryTimeoutInterceptorとJDBCプールを使用するか、statement.setQueryTimeout(320)関数を呼び出しています。内部的なmysqljdbc.jarスレッドを呼び出して、長期実行クエリを取り消します。

Tomcat hotdeploymentはそれを認識しないため、スレッドは実行されたままになり、デッドWebアプリケーションコンテキストがRAMに残ったままになります。

<Resource name="jdbc/BSManager" auth="Container" 
    type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
    initialSize="2" maxActive="100" maxIdle="10" maxWait="30000"  
    username="myuser" password="mypwd" 
    driverClassName="com.mysql.jdbc.Driver" 
    jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor(queryTimeout=320)" 
    url="jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&amp;characterEncoding=utf8" 
     validationQuery="SELECT 1" removeAbandoned="true" removeAbandonedTimeout="7200" 
     testOnBorrow="true" maxAge="1800000" 
    /> 

この警告メッセージThe web application [TI] appears to have started a thread named [MySQL Statement Cancellation Timer] but has failed to stop itは、このリスナーはtomcat/conf/server.xmlファイルで有効化されている場合でも起こります。クエリのタイムアウト後にdead webappが解放されたかどうかはわかりません。私はMySQLのJDBCドライバでクエリのタイムアウトを使用しないことに決めました。

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" 
     classesToInitialize="com.mysql.jdbc.NonRegisteringDriver" /> 
関連する問題