我正在尝试使用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个线程尝试并行访问此代码并引发并发修改异常。
据我所知,可以通过为synchronized块提供类级锁来修复它。但它会严重影响性能。
对此更好的解决方案?
答案 0 :(得分:1)
对我而言,您的问题与info
更相关,Properties
显然是共享Properties
的实例。知道Hashtable
扩展Hashtable
和ConcurrentModificationException
会抛出Hashtable
,如果您按照javadoc中所述的方式更改其结构:
如果
ConcurrentModificationException
在结构修改后的任何时间 迭代器以任何方式创建,除非通过迭代器自己创建 删除方法,迭代器会抛出一个Hashtable
。
如果您有多个线程并行调用此方法,他们可以同时删除修改DriverManager.getConnection(connectionPoolUrl, info)
结构的属性,并在ConcurrentModificationException
内迭代它,最终会得到{{1} }}
您应该做的是将info
转换为线程安全的ConcurrentHashMap<Object, Object>
,并允许同时修改和迭代。然后,您将DriverManager.getConnection
的{{1}}实例作为参数提供给Properties
作为下一个:
info