首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用连接池时并发修改

使用连接池时并发修改
EN

Stack Overflow用户
提问于 2016-11-29 14:34:08
回答 1查看 447关注 0票数 1

我试图在Web应用程序中使用proxool连接池获得jdbc连接。下面的代码描述了相同的内容:

代码语言:javascript
复制
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个线程尝试并行地访问这段代码,并引发并发修改异常。

我理解可以通过为同步块提供类级锁来修复它。但这会严重影响演出。

有什么更好的解决办法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-29 14:59:24

对我来说,您的问题更多地与info有关,它显然是共享的Properties的一个实例。知道Properties扩展了Hashtable,如果在迭代结构的同时改变结构,Hashtable就会抛出一个ConcurrentModificationException,就像javadoc中所说的那样:

如果在创建迭代器之后的任何时候对Hashtable进行了结构修改,那么除了通过迭代器自己的remove方法之外,迭代器将以任何方式抛出一个ConcurrentModificationException

在这里,如果有几个线程并行地调用这个方法,它们可以并发地删除修改Hashtable结构的属性,并在DriverManager.getConnection(connectionPoolUrl, info)中迭代它,这最终会得到一个ConcurrentModificationException

您应该做的是将info转换为线程安全的ConcurrentHashMap,并允许并发修改和迭代。然后将作为参数提供给DriverManager.getConnection,这是一个从info创建的Properties实例,如下所示:

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40868485

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档