【问题标题】:Connection pooling and Thread.interrupt()连接池和 Thread.interrupt()
【发布时间】:2014-09-20 19:12:19
【问题描述】:

我正在使用c3p0 在多线程环境中处理数据库连接池。这个问题可能与其他池库有关,但这就是我所拥有的。

最近我需要直接或间接使用 c3p0 在此类线程上实现 interruption 处理,并注意到如果在 c3p0Datasource.getConnection() 试图从池,它会抛出一个InterruptedException

显然,这是因为wait()

at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1414)

酷。问题是你如何正确处理这个问题 - 两种情况都是 a) 你想在你的线程终止之前继续事务,b) 你想中止。

我尝试了一个似乎运行良好的解决方案(作为答案发布) - 实际上,我认为这个主题已经结束。否则请随意加入,谢谢!

【问题讨论】:

    标签: java connection-pooling c3p0 interrupt-handling interrupted-exception


    【解决方案1】:

    我做了一个简单的测试,在 1 秒内触发大量 Connection 请求,每次执行 SELECT 以确保池瓶颈,然后调用 interrupt()

    我发现connection 对象在InterruptedException 被捕获后很好而且很漂亮,即使堆栈跟踪显示我在awaitAvailable(..) 处出现c3p0 崩溃。就在此时,我正在查看他们的消息来源,当然,他们处理的是InterruptedException。他们甚至会发出适当的警告:

    WARNING: com.mchange.v2.resourcepool.BasicResourcePool@5bcf4b61 -- an attempt to checkout a resource was interrupted, and the pool is still live: some other thread must have either interrupted the Thread attempting checkout!
    

    告诉我们它仍然存在,尽管中间有很多词模糊。解决了。

    无论如何,这是测试。

    ComboPooledDataSource ds = new ComboPooledDataSource();
    
    // testing with various pool sizes - same effect
    ds.setMinPoolSize(1);
    ds.setMaxPoolSize(5);
    ds.setInitialPoolSize(2);
    
    Thread connectingThread = new Thread() {
    
        public void run() {
            Connection cnxn = null;
            while (true) {
                try {
                    cnxn = ds.getConnection();
                    System.out.println("Got connection.);
                    executeQuery(cnxn);
                } catch (SQLException e) {
                    System.out.println("Got exception.");
                    e.printStackTrace();
    
                    // SOLUTION:
                    Throwable cause = e.getCause();
                    if (cause instanceof InterruptedException) {
                        System.out.println("Caught InterruptedException! Cnxn is " + cnxn);
    
                        // note that cnxn is a com.mchange.v2.c3p0.impl.NewProxyConnection
                        // also note that it's perfectly healthy.
                        //
                        // You may either want to:
                        // a) use the cnxn to submit your the query
    
                        executeQuery(cnxn);
                        cnxn.close()
    
                        // b) handle a proper shutdown
    
                        cnxn.close();
    
                    }
                    break;
                }
            }
        };
    };
    
    connectingThread.start();
    
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {          e.printStackTrace();        }
    
    connectingThread.interrupt();
    

    【讨论】:

      猜你喜欢
      • 2012-01-15
      • 2014-10-31
      • 2011-01-26
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      • 2014-12-04
      • 1970-01-01
      • 2017-04-29
      相关资源
      最近更新 更多