Потребители не возвращают соединение в мой пул соединений с БД - PullRequest
2 голосов
/ 08 февраля 2012

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

class Consumer{
    void someMethod(){
        Connection con=Pool.getConnection();
        //some bloody steps which throws exception
        con.goodBye();//giving back the connection to the pool
    }
}

Из-за исключения и, возможно, из-за высокомерия, соединение не всегда возвращается. У меня нет возможности ограничить использование Pool api в классе потребителей.

Как я могу вернуть соединение? (У меня нет способа заставить Потребителя) Я считаю, что для этого нет надежного решения (может быть, я не такой умный). Тем не менее, любой может придумать довольно хорошее решение. Одно из решений, которое я получил, - это проверка того, возникает ли какое-либо исключение в классе Consumer, и если возникает исключение, то полностью возвращаем силу соединения.

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

Ответы [ 5 ]

2 голосов
/ 08 февраля 2012

Это плохой клиентский код. Код должен обработать случай исключения и закрыть соединение, когда закончите.

Там нет никакого способа узнать из своего кода, если это не делается, хотя. Это ошибка и проблема клиентского кода, если он этого не делает.

Наличие разумного тайм-аута - единственный способ ограничить это, но оно все равно не «решает» его, в конечном счете.

-

Вы упоминаете в комментариях, что этот пул используется несколькими клиентами. Конечно, это перекладывает ответственность на вас.

Можете ли вы ограничить каждый клиент одновременным использованием только X-соединений? Таким образом, по крайней мере, они могут связать так много одновременно.

В противном случае вы можете создать отдельные пулы для каждого клиента. Такого рода проблемы просто переносятся в стек, но могут быть уместны в зависимости от используемой логистики.

1 голос
/ 09 февраля 2012

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

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

1 голос
/ 08 февраля 2012

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

здесь - статья, которая поможет вам лучше понять это.

.net также имеет класс WeakReference, который ведет себя очень похоже на это.

0 голосов
/ 08 февраля 2012

Единственный способ, который я могу придумать, - это не предоставить потребителям доступ к пулу подключений напрямую, а иметь собственный список подключений. Затем восстановите соединение после тайм-аута, скажем, 60 секунд.

0 голосов
/ 08 февраля 2012

Вы пытались перехватить исключение и закрыть соединение в предложении catch?

class Consumer{
    void someMethod(){
        Connection con=Pool.getConnection();
        try{
             //some bloody steps which throws exception
        }catch(Exception e){
             con.goodBye();
        }
        con.goodBye();//giving back the connection to the pool
    }
}

Редактировать: вы также можете использовать блок finally, чтобы удалить избыточный код и убедиться, что ваше соединение закрывается в каждом случае. Я предполагаю, что это код Java, нет опыта работы с C #.

...