Как стать автором
Обновить

Комментарии 35

1) Название методов жестокое.
2) метод getAvailableConnsCnt — может врать
3) Чем обусловлено использование Vector?
4) Что если мы попытаемся положить Connection созданный вне нашего пула?

Непонятно на кого рассчитана статья, такое любой начинающий программист(изучивший базовые вещи по синхронизации в java)может сам написать.
Для начинающих и растерявшихся и предназначена)
Для не начинающих, используйте готовые пуллы: bonecp, c3p0, apache и тд.
Я бы даже рекомендовал прямо наоборот:
> для начинающих, используйте готовые пуллы: bonecp, c3p0, apache и тд.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Api у Vector удобней в данном случае Api ArrayList своим lastElement()
Тогда, может быть, лучше какой-нибудь Set? У вас сейчас в putback поиск при удалении за линейное время происходит.
Java SE, предполагается что приложение небольшое. Соединений не тысячами, даже не сотнями, сколько потоков создается столько и соединений, возможно чуть больше. Здесь разница в скорости не столько важна
А если таких не оптимальных мест в приложении +1000? В разных местах не только в пуле. Там где оптимальней было бы использовать связанный список вместо массива.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Чем плох Vector в данном контексте по-вашему?
Можно 2 раза один и тот же Conection положить в него.
Нет, не будет такого. Каждый раз создается новое соединение, как в
for (int i = 0; i < initConnCnt; i++) 
{
	availableConns.addElement(getConnection());
}

так и в
if (availableConns.size() == 0) {
			newConn = getConnection();
}

А в putback выпадает с ошибкой, если коннекшна нет в usedConns
А вы насчет ошибки уверены? Если взглянуть реализацию Вектора, то при удалении он просто вернет false
да, виноват, putback нужно доработать
как-нибудь так:
public synchronized void checkin(Connection c) throws NullPointerException {
	if (c != null) {
		if (usedConns.removeElement(c)) {
			availableConns.addElement(c);
		} else {
			throw new NullPointerException("Connection not in the usedConns");
		}			
	}
}
Да можно так, ну проще использовать Set который по определению своему нужен для хранения уникальных объектов
Вообще, это даже никакой не ConnectionPool. Т.е. он не выполняет свой основной функции — переиспользование соединений после их закрытия. Правильный ConnectionPool должен возвращать не реальное физическое соединение, а обертку над ним, которая слушает событие onClose, в случае которого ничего на самом деле не закрывает, а кладет соединение обратно в pool для последующего переиспользования.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
подключаем к проекту myBatis (iBatis) и получаем пул из коробки
плюс не нужно напрямую с чистым jdbc иметь дело

ну или воспользоваться c3p0
НЛО прилетело и опубликовало эту надпись здесь
А главное — зачем? (с)

Посмотрите плз исходный код популярных пулов соединений. Уверен, что там вы подчерпнете для себя очень много полезной информации.
Если бы было всё так просто! Первый же Exception сломает весь пул.
Чтобы всё работало правильно, придётся делать обёртки над Connection и Statement, которые ловят исключения и инвалидируют (закрывают) Connection, не кладя его обратно в пул. Вдобавок нужно ограничивать размер пула, а новые соединения открывать вне synchronized, чтобы избежать нежелательных задержек в многопоточном приложении.
Рекомендую всем желающим хороший пример реализации Connection Pool от MyBatis.

Довольно понятный код и учитываются все аспекты данного вопроса:
— ограничение сверху на макс.количество соединений
— обработка ошибок соединения
— обновление пула соединений новыми, при обрыве старых

Я даже брал когда-то этот код для реализации пула сокетов.
Подход серьезный, спору нет. Спасибо за ссылку
Похоже, ошибка закралась изначально в предпосылке:
Ведь сервера приложений у нас в данном случае нет, следовательно, использовать Data Source мы не можем


Ну и так вот, конечно, не делается:
try { conn = DriverManager.getConnection(url); } catch (Exception e) { e.printStackTrace(); }

велосипед не нужен [x]
Какая вообще связь между пулом и аппсервером?
Да в самом деле реализаций на просторах интернета тьма тьмущая.
Например: svn.l2jserver.com/trunk/L2J_Server/java/com/l2jserver/L2DatabaseFactory.java
Пример использования: svn.l2jserver.com/trunk/L2J_Server/java/com/l2jserver/gameserver/datatables/ClanTable.java

Естественно, вместо c3p0 пула можно юзать стандартный пул Java.
Возвращать надо не java.sql.Connection, а обертку, у которой метод close() возвращает соединение в пул. Ведь Connection у нас реализует интерфейс AutoCloseable.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории