代码之家  ›  专栏  ›  技术社区  ›  Charles Bretana

使用多个线程和连接池时避免连接超时

  •  2
  • Charles Bretana  · 技术社区  · 16 年前

    我将一个只读数据库操作分成多个块(每个块读取大量数据的一个子集,对其进行分析,并将结果写入磁盘文件)。

    每个块在一个新的.NET线程上(使用委托和BeginInvoke)执行一个选择(到数据表中)

    数据的子集比池中的可用连接多,所以当连接用完时,在释放第一个连接之前,后续的连接请求将排队…直到连接超时到期,然后我得到一个超时异常。

    我该怎么做呢,a)当池中的连接都在使用时禁止超时连接异常,或者b)在我要求另一个连接之前检测到它们都在使用,这样我就可以等到一个连接可用后再询问了?

    1 回复  |  直到 16 年前
        1
  •  1
  •   Aaron Digulla    16 年前

    两种解决方案:

    a)将连接池配置为超时几天。这将阻止挂起的任务,直到返回连接。缺点:当任务挂起时,这不起作用。

    b)使用线程池和工作队列。线程池必须与连接池大小相同(即每个线程一个连接)。将所有工作放入队列中,让任务从队列中提取工作项,直到队列为空。

    解决方案B的伪代码:

    public class Setup
        connPool = createConnectionPool(100);
        queue = createWorkQueue();
        putAllWorkItemsInQueue(queue);
        for (int i=0; i<connPool.size(); i++) {
            t = new WorkerThread(queue)
            list.add(t);
            t.start();
        }
        while (queue.size() != 0) {
            Thread.sleep(1000);
        }
        for (thread in list) {
            thread.interrupt();
        }
    
    public class WorkerThread
        run() {
            while (true) {
                try {
                    workUnit = queue.get(); // This blocks
                    process(workUnit);
                } catch (InterruptedException e) {
                    break;
                }
            }
        }