2012-05-10 2 views
2

вы можете посмотреть мой пул соединений, если это возможный способ его реализации?Реализация пула подключений Java

public class ConnectionPool { 
    private static List<DBConnection> pool = null; 
    private static int available = 0; 
    private ConnectionPool() {} 

    public static DBConnection getConnection() { 
     if (pool == null) { 
      pool = new ArrayList<DBConnection>(); 
      for (int i = 0; i < 3; i++) { 
       try { 
        pool.add(new DBConnection()); 
        available++; 
       } catch (SQLException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     if (pool.size() > 0) { 
      available--; 
      return pool.remove(available); 
     } else { 
      return null; 
     } 
    } 

    public static void returnConnection(DBConnection c) { 
     pool.add(c); 
     available++; 
    } 
} 

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

Connection connection = ConnectionPool.getConnection(); 
    connection.execute("insert into users values('"+user.getUsername()+"', '"+user.getPassword()+"', '"+user.getGroup()+"', '"+banned+"', '"+broker+admin+sharehodler+company+"')");  
    ConnectionPool.returnConnection(connection); 
    connection = null; 

Пожалуйста, мне нужна обратная связь об этой реализации. Спасибо

+1

Почему вы хотите изобрести колесо. Существует множество проверенных и проверенных реализаций пула соединений. – Seshagiri

+0

Зачем вы это делаете? [javax.sql.DataSource] (http://docs.oracle.com/javase/6/docs/api/javax/sql/DataSource.html) уже выполняет объединение пулов, если поставщик выполнил его, что они делают, и в Apache Commons есть хороший. – EJP

+4

Цель состоит в том, чтобы узнать и понять шаблон проектирования пула подключения –

ответ

6

Есть некоторые моменты, которые делают эту реализацию очень проблематичной.

  • Безопасность потоков. Что делать, если несколько потоков работают с пулом? Вы не блокируете список при доступе к чтению/записи.
  • Статический максимальный размер пула из 3 подключений, также вы сразу же создаете все, независимо от того, нужны они или нет. Общая стратегия состоит в том, чтобы создать связку соединений и создать еще больше, когда это необходимо, до тех пор, пока не будет достигнут разрешенный/настроенный максимум.
  • У вас есть только статические методы. Должно быть возможно иметь несколько пулов, то есть вам нужны экземпляры ConnectionPool.
  • Невозможно передать host + dbname + user + пароль для создаваемых соединений.
  • Вы не имеете дело с «сломанными» соединениями - вам, возможно, придется воссоздать соединение, если существующий подключен. Это гораздо более актуально, чем я думал, прежде чем начать использовать пулы.
  • Используйте конфигурационные значения вместо статических значений, смотрите пункт # 2
  • Наконец: Конечно, это интересно писать этот материал самостоятельно - но если вам нужен бассейн для проекта, выбрать существующую, такой как c3p0 или tomcat connection pool.

Я уверен, что есть еще что сказать, но если они не исправлены, нет смысла продолжать.

3

Некоторые мысли:

  • Ваш код не является потокобезопасным. Возможно, поработаешь над этим.
  • Слишком много кода в getConnection(). Является ли ленивая инициализация действительно ?
  • Доступен бесполезно, его можно заменить на pool.size().
2

AFAIK,

  • ваш метод getConnection() необходимо изменить для того, чтобы восстановить только Connection объект.

    Подготовка соединения и объединение должны быть удалены из метода getConnection() и добавлены таким образом, чтобы при первом запуске класса ConnectionPool.

    Также вам необходимо обработать некоторые другие атрибуты, например connection timeout, purging и т. Д., Чтобы он работал для всех сценариев.

    Сделайте его потокобезопасным.

5

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

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

Другие основные вопросы:

  • Что произойдет, если соединение возвращается в середине транзакции?
  • Что произойдет, если соединение каким-либо образом повреждено или отключено? Остается ли он в бассейне?

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

Смежные вопросы