Hibernate не освобождает соединения с источником данных weblogi c при привязке к weblogi c JTA - PullRequest
0 голосов
/ 06 марта 2020

В приложении мы пытаемся связать weblogi c JTA с нашими сессиями гибернации. Наше приложение размещено в Weblogi c 12 C, и у нас есть источник данных, настроенный в weblogi c с минимальным подключением 1 и максимум 150. Это наша конфигурация hibernate.cfg. xml. Мы используем hibernate 5.4.10.

    <property name="connection.datasource">myDataSource</property>
        <property name="jndi.class">weblogic.jndi.WLInitialContextFactory</property>      
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>        
        <property name="show_sql">true</property>
        <property name="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform</property>
        <property name="hibernate.current_session_context_class">jta</property> 
        <property name="hibernate.transaction.coordinator_class">jta</property>

Когда мы пытаемся обработать набор операций, мы замечаем, что соединения не освобождаются из нашего приложения, даже если мы вызываем conn.close() после каждого операция независимо от успеха или неудачи. Когда мы контролировали соединения jdb c в консоли weblogi c на управляемом сервере, мы обнаружили, что активных соединений осталось 150, когда первые 150 сеансов были открыты из спящего режима.

Они так и не были освобождены, пока Контейнер weblogi c достиг тайм-аута (в нашем случае это 900 с). На рисунке ниже показаны детали подключения через 900 с. Мы не видели никаких протекших соединений в течение всей операции.

enter image description here

Вопрос:

  1. Есть ли еще какие-либо отсутствует конфигурация, которая позволит контейнеру weblogi c возвращать соединение с пулом соединений после очистки в ходе транзакции?
  2. Можем ли мы сделать что-то еще в нашем приложении в классе hibernate для освобождения соединение обратно в пул соединений контейнера.

Обновление: добавление фрагментов кода

Инициирование соединения

private Session getSession() throws HibernateException {
        // Get the datasource name to which the Entity is attached to.
        String dataSourceName = getDataSourceName();
        if(isAutoConnectionClose){
            logger.debug("AutoconnectionClose is true. Opening session");
            SessionFactory sessionFactory = getSessionFactory(dataSourceName);
            return sessionFactory.openSession();
        }else{
            logger.debug("AutoconnectionClose is false. Getting session");
            return HibernateSessionManager.getSession(dataSourceName);
        }
    }

Здесь мы используем AutoconnectionClose is true.

Затем мы выполняем операцию

public Entity importEntity(Entity entity) throws CreateException, UpdateException {
        if(logger.isDebugEnabled()) logger.debug("Importing entity : " + entity.getClassName());
        SessionImpl session = null;
        try{
            session = (SessionImpl) getSession();

            beginTransaction(session);
            session.setCacheMode(CacheMode.IGNORE);
            //Save the entity values to the hibernate cache
            session.saveOrUpdate(entity);

            // Syncs the hibernate cache with the database
            session.flush();
            return entity;
        }catch (HibernateException hbe){

            throw new CreateException(hbe,"sys.entity.create", new Object[]{entity.getClassName()} ,
                    "The records could not be created.");
        } finally{
            cleanUp(session);
        }
    }

И затем выполняем очистку.

private void cleanUp(Session session){
        if(isAutoConnectionClose){
            try{
                if(session != null){
                    SessionImpl sessionImpl=(SessionImpl)session;
                    Connection conn=sessionImpl.connection();
                    conn.close();
                    session.close();
                }
            }catch(Exception ex){
                ex.printStackTrace();
            }
        }
    }

Мы убедились из журналов, что количество открытых и закрытые сеансы совпадают, т.е. мы закрываем все открытые соединения. Спасибо

...