2016-11-29 6 views
1

Webアプリケーションでproxool接続プールを使用してjdbc接続を取得しようとしています。コードの下に同じことを説明します。私は私のサーバーを起動すると何が起こることは、すぐにある接続プール使用時の同時変更

public static Connection getConnection(String key, boolean useConnectionPool, String poolName) { 
    Connection connection = null; 
    String alias = "DBCP" + poolName + "_" + key; 
    String driverClass = "com.mysql.jdbc.Driver"; 
    checkAndLoadProps(); 
    String driverUrl = "jdbc:mysql://" + props.getProperty(key + "_DBMS_URL") + "/" + props.getProperty(key + "_DEF_SCHEMA") + "?autoReconnect=true&useUnicode=true&characterEncoding=utf8&jdbcCompliantTruncation=false&rewriteBatchedStatement=true"; 
    String connectionPoolUrl = "proxool." + alias + ":" + driverClass + ":" + driverUrl; 
    try { 
     if (useConnectionPool) { 
      info.remove("user"); 
      String user = props.getProperty(key + "_CLIENT"); 
      info.setProperty("user", user); 
      info.remove("password"); 
      String password = props.getProperty(key + "_CLIENT_PASS"); 
      info.setProperty("password", password); 
      String host = props.getProperty(key + "_DBMS_URL"); 

      synchronized (poolName) { 
       connection = DriverManager.getConnection(connectionPoolUrl, info); 
      } 

     } 
     if (connection != null) { 
      return connection; 
     } else { 
      System.out.println("DB Connection Not Established"); 
     } 

    } catch (Exception ex) { 
     System.out.println("DB Connection Not Established::" + ex.getMessage()); 
     ex.printStackTrace(); 
    } 
    return null; 
} 

、1つの以上のスレッドが並列にこのコードにアクセスしようとすると、それは同時変更例外がスローされます。

同期ブロックにクラスレベルのロックを設定することで修正できることを理解します。しかし、それはパフォーマンスに深刻な影響を与えます。

もっと良い解決法はありますか?

+0

あなたはスタックトレースを追加してくださいだろうか? –

+1

'info 'の定義方法も表示してください –

答えて

1

あなたの問題は、明らかにPropertiesのインスタンスであるinfoに関連しています。

Hashtableが構造 反復子が作成された後、いつでも変更された場合には、:PropertiesHashtableを拡張したjavadocに述べたように、それを反復処理しているときに、その構造を変更した場合HashtableConcurrentModificationExceptionがスローされますことを知っイテレータ自身の メソッドを除いて、イテレータは ConcurrentModificationExceptionをスローします。

そして、ここであなたは、彼らが同時にあなたのHashtableの構造を変更するプロパティを削除し、ConcurrentModificationExceptionで終わることになるDriverManager.getConnection(connectionPoolUrl, info)以内にそれを反復処理することができ、並列に、このメソッドを呼び出して、いくつかのスレッドを持っている場合。

infoをスレッドセーフであるConcurrentHashMap<Object, Object>に変換して、同時に変更および反復することができます。そして、あなたはDriverManager.getConnectionにパラメータとして提供する、次のようinfoから作成Propertiesインスタンス:

private static Map<Object, Object> info = new ConcurrentHashMap<>(); 

public static Connection getConnection(String key, boolean useConnectionPool, 
    String poolName) { 

    ... 
    Properties properties = new Properties(); 
    properties.putAll(info); 
    connection = DriverManager.getConnection(connectionPoolUrl, properties); 
+1

これは本当に問題でした。私はあなたが提案した修正を試してみました。どうもありがとう ! – user2730428

関連する問題