Соединение с базой данных не освобождается после вызова метода закрытия сеанса Hibernate - PullRequest
0 голосов
/ 12 февраля 2020

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

Я использую MySQL в качестве сервера базы данных, Tomcat в качестве сервера веб-приложений и Hibernate в качестве среды хранения. Когда я подключаюсь к веб-серверу Tomcat, использую Hibernate для записи данных в MySQL из сервлета, например:

public class ImgServlet extends HttpServlet{
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        ... 
        //do something
        ...
        writeToDatabase(ipAddr, hostname, action);
        ...
        //do something
        ...
    }

    private void writeToDatabase(String ipAddr, String hostname, EStorageLocation location, EStorageAction action, String filename){
        Configuration config = new Configuration().configure("com/test/ath/hibernate.cfg.xml");
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Transaction transaction = null;
        StorageLog log = new StorageLog(ipAddr, hostname, action);
        try{
             transaction = session.beginTransaction();
             session.save(log);
             transaction.commit();
        }catch(Exception e){
            if(transaction != null){
                transaction.rollback();
            }
            e.printStackTrace();
        }finally{
            session.close();
        }   
    }
}

Каждый раз, когда я вызываю этот сервлет, Max_used_connections в MySQL увеличение 1 и «Threads_connected» также увеличивается 1.

Я могу проверить это в MySQL Консоль.

mysql> show global status like 'Max_used_connections';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Max_used_connections | 15    |
+----------------------+-------+
1 row in set (0.00 sec)

mysql> show status like 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 15    |
+-------------------+-------+
1 row in set (0.00 sec)

Когда эти значения достигают 151, это настройка max_connections в моем MySQL, тогда мое приложение получит исключение "Too many connection" из MySQL и больше не сможет подключиться к MySQL, если не перезапустит Tomcat или MySQL.

Мой файл hibernate.cfg. xml выглядит так:

<hibernate-configuration>
    <session-factory>
        <property name="show_sql">true</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://127.0.0.1:3306/tth</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="javax.persistence.validation.mode">auto</property>

        <property name="hibernate.connection.CharSet">utf8</property>
        <property name="hibernate.connection.characterEncoding">utf8</property>
        <property name="hibernate.connection.useUnicode">true</property>

        <mapping resource="com/yabtogo/ath/server/StorageLog.hbm.xml" />
    </session-factory>
</hibernate-configuration>

Что я не понимаю:

  1. Почему у меня есть вызвал session.close (), но соединение, похоже, не освобождается точно.

  2. Я не использую никаких механизмов пулов соединений, как в моем файле hibernate.cfg. xml , так это использовать по умолчанию встроенный пул hibernate? но каков размер пула?

  3. Соединения, которые были созданы из сервлета, все еще находятся во встроенном пуле после события session.close ()? Или эти соединения на самом деле помещены в пул встроенных соединений по умолчанию, предоставленный Tomcat?

  4. Поможет ли мне установить свойство "hibernate.connection.release_mode" в значение "on_close" или "after_transaction" или "after_statement" в моем файле hibernate.cfg. xml для подключения к базе данных, освобожденного сразу после вызываемого метода session.close ()?

  5. или это поможет, если я установить для свойства "hibernate.connection.pool_size" значение 1?

1 Ответ

0 голосов
/ 13 февраля 2020

Добавление этих свойств в Hibernate.cfg. xml будет работать как шарм.

<</p>

property name="hibernate.c3p0.max_size">15</property>
        <property name="hibernate.c3p0.max_statements">0</property>
        <property name="hibernate.c3p0.min_size">3</property>
        <property name="hibernate.c3p0.timeout">25200</property>
        <property name="hibernate.c3p0.validate">true</property>
        <property name="hibernate.c3p0.autoCommitOnClose">false</property>
        <property name="hibernate.c3p0.acquireRetryDelay">1000</property>
        <property name="hibernate.c3p0.acquireRetryAttempts">60</property>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...