连接池和Thread.interrupt()

3
我正在使用c3p0来处理多线程环境下的数据库连接池。这个问题可能涉及到其他连接池库,但这就是我所拥有的。
最近,我需要在这些线程上直接或间接地使用c3p0实现interruption handling,并注意到如果在c3p0Datasource.getConnection()试图从池中获取Connection时立即调用interrupt(),它会抛出一个InterruptedException
显然,这是由于wait()引起的。
at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1414)

很好。问题是如何正确处理这个问题 - 无论是情况a)在您的线程终止之前要继续事务,还是b)想要中止事务。
我已经尝试了一种看起来运行良好的解决方案(发布为答案) - 实际上,我认为这个主题已经关闭。否则,请随意参与讨论,谢谢!
1个回答

3

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

我发现,在捕获InterruptedException后,connection对象是正常的,即使堆栈跟踪显示c3p0在awaitAvailable(..)处崩溃。此时,我正在查看它们的源代码,当然,他们处理了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();
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接