Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > создается много процессов postgres


Автор: implements 29.7.2010, 07:57
Есть класс отвечающий за работу с БД, реализован он как singleton, в приватном конструкторе создаю подключение к БД, и в методах реализована логика(всякие селекты и insert-ы), и вот ложу все это дело на веб-сервер tomcat и начинаю вызывать методы, и с каждым вызовом появляется в процессах новый просесс postgres, и ка вы поняли через время это все дело валится

Код

    public class DataBase { 
    private static DataBase Instance; 
    private static Connection con; 
    private Statement statement; 
    private String sqlcommand; 
    public static DataBase getInstance(){ 
    if(Instance==null) 
    Instance=new DataBase(); 
    return Instance; 
    } 
    private DataBase (){ 
    connectBase(); 
    } 
    public void connectBase() { 
    String username = "postgres"; 
    String password = "123456"; 
    String url = "jdbc:postgresql://localhost:5432/db"; 
    try { 
    Class.forName("org.postgresql.Driver"); 
    con = java.sql.DriverManager.getConnection(url, username, password); 
    statement = con.createStatement(); 
    } catch (ClassNotFoundException e) { 
    e.printStackTrace(); 
    } catch (SQLException e) { 
    e.printStackTrace(); 
    } 
    } 
      
    public String PutFTPFromBase() 
                throws Exception { 
    sqlcommand = "select * from table"; 
    try { 
    res = statement.executeQuery(sqlcommand); 
    } 
    res.close(); 
    } catch (SQLException e) { 
    e.printStackTrace(); 
    } 
    } 
      
      
    }

Автор: witex 29.7.2010, 18:31
Цитата

 try { 
    res = statement.executeQuery(sqlcommand); 
    } 
    res.close(); 
    } catch (SQLException e) { 
    e.printStackTrace(); 
    } 

А как это компилируется?

Автор: dobrolub 29.7.2010, 18:37
у тебе текут объекты java.sql.Connection, а создание процессов postgres – один из эффектов течи. На каждый новый connectBase() создаётся новый Connection, который не закрывается. 

Почитай tutorial по JDBC

Автор: implements 30.7.2010, 07:10
witex,  что значит как?
dobrolub,  Дык у меня оъект DataBase существует в одном экземпляре, и в его приватном конструкторе я создаю java.sql.Connection, следовательно и он будет в одном экземпляре, правильно?

Да кстати делал по простому, каждый раз создавал java.sql.Connection и закрывал его, всеравно  процесс postgres не уничтожался.

Автор: dobrolub 30.7.2010, 07:41
Надо добавить System.out.printlns и убедиться, что это именно так. Из кода который ты показал это не очевидно.

Автор: implements 30.7.2010, 07:47
dobrolub,  
Этот код не показывает?

Код

 public static DataBase getInstance(){ 
       if(Instance==null) 
           Instance=new DataBase(); 
       return Instance; 
 } 
    private DataBase (){ 
    connectBase(); 
    } 

Автор: dobrolub 30.7.2010, 07:51
Class Database - public, method connectBase – public . следовательно из другого места программы может вызываться много раз.

Автор: implements 30.7.2010, 07:57
dobrolub,  Мда а Вы знаете как я его вызываю методы этого класса?
а вот так вот
Код

DataBase.getInstance(). METHOD();

Это такой шаблон, я явно не создаю объект
Код

DataBase db=new DataBase();

За это отвечает статический метод getInstance(), это так на всякий случай если Вы не знаете!

Автор: dobrolub 30.7.2010, 08:21
Ну например такой код даст Connection leak:

Код

for (int i = 0; i < 10; i++)
  DataBase.getInstance().connectBase();


Я бы добавил System.out.println  в код перед выделением Connection, чисто чтобы убедиться. Весь твой код я не смотрю же. Ты только один класс показал.

Автор: implements 30.7.2010, 10:59
Цитата(dobrolub @  30.7.2010,  08:21 Найти цитируемый пост)
for (int i = 0; i < 10; i++)  DataBase.getInstance().connectBase();

А зачем так???? 

когда вызывается getInstance(), то он смотрит создан класс или нет, если создан, то возвращает ссылку на него, а если нет, то создает и возвращает, в этом я уверен это же ведь singleton!!!

Автор: aleksandy 30.7.2010, 12:54
Цитата(implements @  30.7.2010,  10:59 Найти цитируемый пост)
в этом я уверен это же ведь singleton

Не будь таким уверенным... Твой код в многопоточном приложении запросто может создать несколько экземпляров connection. http://www.skipy.ru/technics/singleton.html

И statement лучше создавать и закрывать для каждого запроса заново.

Автор: implements 30.7.2010, 13:13
Цитата(aleksandy @  30.7.2010,  12:54 Найти цитируемый пост)
Не будь таким уверенным... Твой код в многопоточном приложении запросто может создать несколько экземпляров connection

Знаю, но приложение однопоточное=), но ладно что ыло легче я синхронизирую все это дело!


Цитата(aleksandy @  30.7.2010,  12:54 Найти цитируемый пост)
И statement лучше создавать и закрывать для каждого запроса заново.

Делал и statement и connection открывал и закрывал с каждым новым обрашением, НО приэтом процессы не удалялись, при создании каждый раз новый создается!!!

Автор: implements 30.7.2010, 13:42
Впринципе когда каждый раз закрываю и открываю connection, res и statment то работает нормально!
Но все-же класс управления БД должен быть в одном экземпляре!

Автор: dobrolub 30.7.2010, 17:50
Цитата(implements @ 30.7.2010,  10:59)
Цитата(dobrolub @  30.7.2010,  08:21 Найти цитируемый пост)
for (int i = 0; i < 10; i++)  DataBase.getInstance().connectBase();

А зачем так???? 

Я хотел обратить внимание на твой метод connectBase() (не getInstance()). connectBase – public и может быть вызван из другого места программы много раз.

>Да кстати делал по простому, каждый раз создавал java.sql.Connection и закрывал его, всеравно  процесс postgres не уничтожался.
процесс будет висеть если он ещё используется драйвером, или когда он ещё в пуле процессов postgres для новых клиентов.

Посмотри на драйвер, может его надо сменить / обновить версию.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)