Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Tomcat6 и Connection pool, ошибка при закрытии коннекта 
:(
    Опции темы
Atum
Дата 5.2.2013, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 3.10.2008

Репутация: нет
Всего: нет



 Добрый день ! 
В стандартном tomcat 6  возникла ошибка - при долгом простое сервера если к  нему никто не обращался коннектор с базой разрывался и не восстанавливался  ? может у кого была такая ошибка? как с ней бороться ? 

Начало темы тут  (настройки второе сообщение с конца )

http://forum.vingrad.ru/index.php?showtopi...t&p=2533182

Код

Caused by: java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3345)
        ... 33 more
org.apache.jasper.JasperException: javax.servlet.ServletException: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server 
was 56  ,194,727 milliseconds ago.  The last packet sent successfully to the server was 56,194,728 milliseconds ago. is longer than the server configured value of 'wait_timeout'.

 You should consider either expiring and/or testing connection validity before use in your application, 
increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.


Решил  разобраться с Пулом соединений.

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


описание context.xml  
Код

     <Resource    auth="Container" 
              description="DB Connection"
          driverClass="com.mysql.jdbc.Driver"
          maxPoolSize="4"
          minPoolSize="2"
          acquireIncrement="1"
          name="jdbc/mytest" 
          user="*******" 
          password="******" 
          factory="org.apache.naming.factory.BeanFactory"
          type="com.mchange.v2.c3p0.ComboPooledDataSource"
          jdbcUrl="jdbc:mysql://127.0.0.1:3306/*****?characterEncoding=UTF-8"
/>


что делаю : 

у меня есть класс 
Код


  private ConnectionFactory() {
  }
    
        public static synchronized Connection getConnection() {
        if (con == null) {
            try {
                Context ctx = new InitialContext();
                dataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/mytest");
                con = dataSource.getConnection();
            } catch (NamingException e) {
                Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE,  e.getMessage() , e); 
            } catch (SQLException e) {
                Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE,  e.getMessage() , e); 
            }
        }
        return con;
    }




Делаю два вызова так : 

int count =  getMessageCount();
count =  getMessageCount();

получаю 

com.mchange.v2.c3p0.impl.NewProxyConnection) com.mchange.v2.c3p0.impl.NewProxyConnection@19cd29f
при первом обращении : а после закрытия ошибку : 

 java.sql.SQLException: You can't operate on a closed Connection

 как работать с  пулом коннектов , У меня видимо есть какое то недопонимание вопроса !?

Код



    public Integer getMessageCount() throws SQLException {
        Statement stmt = null;
        ResultSet rs = null;
        Integer result = 0;
        try {
            stmt = getConnection().createStatement();
            rs = stmt.executeQuery("select count(*) as count from MESSAGE");

            while (rs.next()) {
                result = rs.getInt("count");
            }
        } finally {

            if (rs != null) {
                rs.close();
            }

            if (stmt != null) {
                stmt.close();
            }

            if(getConnection()!=null){
                getConnection().close();
            }

            
        }
        return result;
    }


При повторном обращении к getConnection().createStatement() 

сам  объект con -  не null ? но из за того что я его закрыл - внутри его все ссылки null /
 из за этого, видимо , и вылетает ошибка .

Это сообщение отредактировал(а) Atum - 5.2.2013, 12:13
PM MAIL   Вверх
danilych
Дата 5.2.2013, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 2.2.2011

Репутация: нет
Всего: 3



вот такая строка коннекта мне помогла jdbc:mysql://localhost/mydb?autoReconnect=true
PM MAIL   Вверх
Atum
Дата 5.2.2013, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 3.10.2008

Репутация: нет
Всего: нет



Цитата(danilych @ 5.2.2013,  10:59)
вот такая строка коннекта мне помогла jdbc:mysql://localhost/mydb?autoReconnect=true

Это для первой ошибки для стандартного tomcat6 !?



А кто что может рассказать по поводу Пула ?

как я понимаю действовать надо иначе : 

Код

     public static synchronized Connection getC3p0Connection() {
        if (poolDataSource == null) {
            try {
                Context ctx = new InitialContext();
                poolDataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/mytest");
                
            } catch (Exception e) {
                Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE,  e.getMessage() , e); 
            }
        } 
        try{
          c3p0Con = poolDataSource.getConnection();
        }catch(SQLException exception){
              Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE,  exception.getMessage() , exception); 
        }
        return c3p0Con;
    }



Код

    public Integer getMessageCount() throws SQLException {
        Statement stmt = null;
        ResultSet rs = null;
        Connection connection = getC3p0Connection();
        Integer result = 0;
        try {
            stmt = connection.createStatement();
            rs = stmt.executeQuery("select count(*) as count from MESSAGE");

            while (rs.next()) {
                result = rs.getInt("count");
            }
        } finally {

            if (rs != null) {
                rs.close();
            }

            if (stmt != null) {
                stmt.close();
            }
            
            if(connection!=null){
                connection.close();
            }
            
        }
        return result;
    }


Если я правильно понимаю то poolDataSource - будет возвращать мне каждый раз новый коннект - из своего пула 

и ошибок не будет ?!

Это сообщение отредактировал(а) Atum - 5.2.2013, 11:50
PM MAIL   Вверх
Старовъръ
Дата 5.2.2013, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.5.2008

Репутация: 1
Всего: 10



Цитата
вот такая строка коннекта мне помогла jdbc:mysql://localhost/mydb?autoReconnect=true 
Этого стоит избегать, во-первых оно не предотвратит исключение, во-вторых может сказаться на консистентности данны если правильно не обрабатывать SQLException. Подробнее:
Цитата
Should the driver try to re-establish stale and/or dead connections? If enabled the driver will throw an exception for a queries issued on a stale or dead connection, which belong to the current transaction, but will attempt reconnect before the next query issued on the connection in a new transaction. The use of this feature is not recommended, because it has side effects related to session state and data consistency when applications don't handle SQLExceptions properly, and is only designed to be used when you are unable to configure your application to handle SQLExceptions resulting from dead and stale connections properly. Alternatively, as a last option, investigate setting the MySQL server variable "wait_timeout" to a high value, rather than the default of 8 hours.
Также об этой опции детально можно прочесть здесь.
Вместо этого нужно сконфигурировать пул слать минимальные запросы с какой-то частотой (по умолчанию MySQL разрывает соединение через 8 часов). Пример настройки connection pool'a можно найти здесь, он правда настроен на стороне приложения, а не Tomcat JNDI.
PM MAIL WWW   Вверх
COVD
Дата 6.2.2013, 06:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 4
Всего: 43



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

PM MAIL   Вверх
Atum
Дата 6.2.2013, 08:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 3.10.2008

Репутация: нет
Всего: нет



Цитата(COVD @ 6.2.2013,  06:52)
Новый или тот же самый - вас не должно интересовать. Коннекшен надо всегда брать из DataSource и закрывать, а не присваивать его статической переменной, т.е. не дублировать DataSource. Ошибка в этом.

т.е. не дублировать DataSource. Ошибка в этом.

Пример можно ?


Чем плохо решение с ConnectionFactory и  poolDataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/mytest");
poolDataSource - создается один раз.

от него я буду каждый раз брать Connection.


Или его нужно делать не статиком ? и каждый раз сначала получать DataSource через lookup
Код


public static synchronized Connection getConnection(){
....
DataSource poolDataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/mytest");

а потом 
Connection connection = poolDataSource .getConnection();

return connection ;

}

PM MAIL   Вверх
COVD
Дата 6.2.2013, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 4
Всего: 43



Цитата

Чем плохо решение с ConnectionFactory и  poolDataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/mytest");
poolDataSource - создается один раз.

от него я буду каждый раз брать Connection.


Именно так и надо. Переменная connection должна быть локальной, а вы ее делали статической и это вносило путаницу.

 
Код

       
        Connection connection = poolDataSource .getConnection();
       
        try {
                ..........................
            
        } finally {

            ............
            
            if(connection!=null){
                connection.close();
            }
            
        }
 
PM MAIL   Вверх
Atum
Дата 7.2.2013, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 3.10.2008

Репутация: нет
Всего: нет



Цитата(COVD @ 6.2.2013,  20:18)
Цитата

Чем плохо решение с ConnectionFactory и  poolDataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/mytest");
poolDataSource - создается один раз.

от него я буду каждый раз брать Connection.


Именно так и надо. Переменная connection должна быть локальной, а вы ее делали статической и это вносило путаницу.

 
Код

       
        Connection connection = poolDataSource .getConnection();
       
        try {
                ..........................
            
        } finally {

            ............
            
            if(connection!=null){
                connection.close();
            }
            
        }

А Если класс в котором будет использоваться Connection  и в котором реализована функция getMessageCount() - будет иметь один инстантс - 

будет  DAO /  чем плохо в нем один раз создать такой коннект и держать его постоянно ?!

Хотя нет гарантии что при долгом " провисании , бездействии" - коннект может отвалиться ?! так ?






так же вопроспо поводу DataSource poolDataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/mytest");

должен ли быть DataSource poolDataSource - один раз создан (в ConnectionFactory ) - или можно каждый раз искать его JNDI контексте и вытаскивать от туда ?

PM MAIL   Вверх
COVD
Дата 7.2.2013, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 4
Всего: 43



Я обычно создаю DataSource один раз - база данных свой адрес ведь не меняет. А Connection  всякий раз беру и возвращаю в пул. Это хорошо тем, что пул несет ответственность за соединения и его настройками можно регулировать количество соединений и создание новых при необходимости. Эту функциональность не надо программировать, она уже реализована в пуле.
PM MAIL   Вверх
Atum
Дата 11.2.2013, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 3.10.2008

Репутация: нет
Всего: нет



Цитата(COVD @ 7.2.2013,  17:48)
Я обычно создаю DataSource один раз - база данных свой адрес ведь не меняет. А Connection  всякий раз беру и возвращаю в пул. Это хорошо тем, что пул несет ответственность за соединения и его настройками можно регулировать количество соединений и создание новых при необходимости. Эту функциональность не надо программировать, она уже реализована в пуле.

c этим полностью согласен ! Готовый пул это огромное подспорье ! 

Но Пулы тоже пишут люди .Cтолкнулся с тем что в tomcat6  что -то по умолчанию работает не так как надо , перешел на  c3p0 .

Вот теперь хочу еще сравнить что изменилось в tomcat7  .
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0579 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.