2012-11-14 14 views
5

こんにちは私は基本的なストームアプリケーションを設定して、ツイートのストリームを受け取り、MySQLデータベースに格納します。アプリケーションは最初の〜23時間かかります。それでは、次のエラーが発生します。ストーム23時間後にクラッシュする

SQL Exception 
SQL State: 08003 

これが数回終了すると、それが終了します。私は標準のJBDCコネクタを使ってJavaからデータベースに接続しています。

private String _db=""; 
private Connection conn = null; 
private PreparedStatement pst = null; 

public ArchiveBolt(String db){ 
    _db = db; 
} 

private void setupConnection() { 
    //Connect to the database 
    try { 
     Class.forName("com.mysql.jdbc.Driver"); 
     conn = DriverManager.getConnection("jdbc:mysql://localhost:8889/twitter_recording", "root", "root"); 
    } catch (Exception e){ 
     e.printStackTrace(); 
    } 
} 

public void execute(Tuple tuple, BasicOutputCollector collector) { 

    Status s = (Status) tuple.getValue(0); 

    //setup the connection on the first run through or if the connection got closed down 
    try { 
     setupConnection(); 
    } catch (Exception e) { 
     // TODO: handle exception 
     System.out.println(e.toString()); 
    } 


    try { 

     pst = conn.prepareStatement("INSERT INTO " + _db + " (tweet)" + 
            "VALUES (?);"); 

     pst.setString(1, s.toString()); 

     //execute the SQL 
     pst.executeUpdate(); 

    } catch (SQLException ex) { 
     // handle any errors 
     System.out.println("SQLException: " + ex.getMessage()); 
     System.out.println("SQLState: " + ex.getSQLState()); 
     System.out.println("VendorError: " + ex.getErrorCode()); 

     if(ex.getSQLState().equals("08003")){ 
      setupConnection(); 
     } 

    } finally { 
     try { 
      conn.close(); 
     } catch (SQLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

それはので、私はそれがそのエラーを投げた場合、それはセットを再試行することを決めた08003エラーでクラッシュしたことが明らかになった後、次のように保存し、DBの接続を設定するための関数のコードは、しかし、それはどちらも役に立たなかった。誰もがこの問題を解決するための正しい方向に私を指摘できますか?

+0

[08003 \t接続が存在しません](http://dev.mysql.com/doc/refman/5。0/en/connector-odbc-reference-errorcodes.html) –

+0

接続は常に同じ時刻に切断されますか?その場合は、スケジュールされたイベント(DBが毎日再起動されるなど)によって接続が切断されている可能性があります。 –

+0

はい私はこれを知っています。そのため、このエラーが発生した場合に再度接続をセットアップしました。上記のように、catch(SQLException ex){ //エラーを処理します。 System.out.println( "SQLException:" + ex.getMessage()); System.out.println( "SQLState:" + ex.getSQLState());System.out.println( "VendorError:" + ex.getErrorCode()); if(ex.getSQLState()。equals( "08003")){ setupConnection(); } } ' –

答えて

3

After it became apparent that it was crashing because of a 08003 error I decided that if it threw that error it should retry the set up of the connection, however that didn't help either. Could anyone point me in the right direction for solving this issue?

に解決する必要があり、ここで二つの問題基本的にあります。

  • はなぜ接続が最初の場所で迷子になっているが?
  • 再接続しようとしていないのはなぜですか?

最初の問題については、MySQLログを参照して、そこに何らかの兆候がないかどうかを確認する必要があります。また、(繰り返し) "状態080003"例外の直前にSQL例外がないかどうかを確認してください。後者は接続が以前に亡くなったことを伝えるだけです。

  • MySQLサーバが非アクティブが原因の接続をタイムアウトしました:

    私の推測では、問題は、次のいずれかであるということです。これが問題であれば、MySQLの設定で接続タイムアウトを変更することができます。

  • アプリケーションのJDBC接続がゆっくりとリークしている可能性があります。

2番目の問題については、一般的なアプローチは正しいですが、コードが説明と一致しません。実際には、executeメソッドが呼び出されるたびに、のように常にが新しいデータベース接続を確立しようとしています。これにより、例外ハンドラ内の再接続呼び出しが無意味なものになります。 (誰かが...それが動作するように取得しようとする「ことに暴行された」、それがうまく問題の一部とすることができることをOTOH、コードの兆候を示す。)

私はsetupConnectionと呼ばれていることを確認しますにする必要がある場合は、例外がスローされる可能性があります。さらに、デッド接続オブジェクトclose()を明示的に確認して、漏れないように接続管理を再考する必要があります。


レコードの場合、遠い過去に失われた接続を「処理」するために使用された「autoReconnect」という接続URLパラメータがあります。残念ながら、元の実装は安全ではないため、効果的に無効にしました。詳細については、この質問を参照してください:Why does autoReconnect=true not seem to work?

関連する問題