Избегайте тайм-аут соединения при использовании нескольких потоков и пула соединений - PullRequest
2 голосов
/ 02 декабря 2008

Я разделяю операцию базы данных только для чтения на несколько частей (каждый из которых читает подмножество очень большого объема данных, анализирует его и записывает результаты в файл на диске).

Каждый кусок выполняет выбор (в таблицу данных) в новом потоке .net (с использованием делегата и BeginInvoke)

Существует больше подмножеств данных, чем доступных подключений в пуле, поэтому, когда у меня заканчиваются подключения, перед тем как освободить первое, последующие запросы на подключение ставятся в очередь ... до истечения времени ожидания подключения, и тогда я получаю исключение тайм-аута.

Как мне, A) запретить исключение тайм-аута соединения, когда все соединения в пуле используются, или B) обнаружить, что они все используются, прежде чем я даже запросить другое, чтобы я мог ждать, пока оно не будет доступно, прежде чем спрашивать?

1 Ответ

1 голос
/ 02 декабря 2008

Два решения:

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;
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...