2016-12-08 2 views
0

У меня есть приложение Java, которое планирует выполнение задания cron каждые 1 мин. Он работает на Glassfish 4. Мы используем Hibernate с JTA Entity Manager, который управляется контейнером для выполнения запросов в базе данных SQL Server.Приобретенные соединения резко крутятся, приводя к сбою сервера

JDBC Connection Параметры пула являются:

Начальный и минимальный размер пула: 16
Максимальный размер пула: 64
Pool Resize Количество: 4
Idle Timeout: 300
Макс Время ожидания: 60000

JDBC Connection Pool Статистика после 22 часов работы:

NumConnUsed 0count
NumConnAcquired 14404count
NumConnReleased 14404count NumConnCreated 16count
NumConnFree 16count

количество приобретаемых соединений продолжает увеличиваться и происходит сбой Glassfish 4 примерно через 10 дней с исключением ниже.

RAR5117: Не удалось получить/создать соединение из пула соединений [com.beonic.tiv5]. Причина: com.sun.appserv.connectors.internal.api.PoolingException: java.lang.RuntimeException: Got исключение во время XAResource.start:

Пожалуйста, укажите, как избежать Glassfish аварии.

+0

Вы можете поместить код задания работает? Закрываете ли вы закрытие хранилища сохраняемости? – Gatusko

+0

В соответствии с документацией «Контейнер с управляемым консистентным контентом - как указано в названии - управляется корпоративным контейнером. Контейнер несет ответственность за встраивание контекста настойчивости в компоненты предприятия и также несет ответственность за его удаление в конце текущего сделка." Мы не можем явно закрыть менеджеров сущностей в транзакциях, управляемых контейнерами, так как это вызовет IllegalStateException. – Rashmi

+0

Это пример кода примера: public Insight findInsightByName (String name) { \t Context ic; \t EntityManager em; \t Insight loc = null; \t try { \t \t ic = new InitialContext(); \t \t em = (EntityManager) ic.lookup (kTIv5PU); \t \t LOC = (Инсайт) em.createQuery ("выберите д из Insight г ГДЕ d.name =: имя ") \t \t \t .setParameter (" название", название) .getSingleResult(); \t \t \t } \t улов (NamingException ех) {(() TInsightDAO.class.getName) Журнал \t \t Logger.getLogger (Level.SEVERE, нулевой, ех). \t} \t finally { \t \t em = null; \t \t ic = null; \t} \t return loc; } – Rashmi

ответ

0
finally 
{ 
em = null; 
ic = null; 
} 

Я думаю, что здесь есть проблема, которую вы никогда не совершали или закрывая transacction Giving this example and documentation of JTA check 5.2.2

// BMT idiom 
@Resource public UserTransaction utx; 
@Resource public EntityManagerFactory factory; 

public void doBusiness() { 
    EntityManager em = factory.createEntityManager(); 
    try { 

    // do some work 
    ... 

    utx.commit(); 
} 
catch (RuntimeException e) { 
    if (utx != null) utx.rollback(); 
    throw e; // or display error message 
} 
finally { 
    em.close(); 
} 

Это правильный способ делать transacction. Но вы только обнуляете значения и ничего больше, поэтому ваши пулы и не закрыты. Here is more documentation about Transactions

+0

Пример, который вы указали для транзакций, управляемых бинами (BMT). Я использую транзакции, управляемые контейнером (CMT). Ссылка на документ, которую вы отправили, содержит информацию об этом. Все закрытие и откат управляется контейнером. Если мы попытаемся закрыть явно, это вызовет IllegalStateException. – Rashmi

0

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

Рекомендуется установить проверку соединения, которая обеспечивает повторное открытие соединений при закрытии внешним сервером.

Существует тщательная статья о connection pools in Glassfish/Payara, выписка особенно раздел о (с использованием Derby DB в примере):

Для включения соединения проверки:

asadmin набор resources.jdbc- connection-pool.test-pool.connection-validation-method = custom-validation

asadmin set resources.jdbc-connection-pool.test-pool.validation-classname = org.glassfish.api.jdbc.validation.DerbyConnectionValidation

asadmin набор resources.jdbc-соединение-pool.test-pool.is-соединение валидация-требуется = истина

+0

Я включу проверку и проверку соединения. У вас есть идея, как диспетчер сущностей спящего режима в транзакциях, управляемых контейнером (CMT), имеет дело с открытием и закрытием соединений. Создает ли соединение для каждого выполненного запроса. – Rashmi

+0

В транзакциях, управляемых контейнерами, hibernate просто запрашивает соединение из контейнера каждый раз (я не уверен, что для каждого запроса или один раз за транзакцию, но я думаю, что только один раз за транзакцию). Он не занимается открытием/закрытием, он просто получает соединение. Если он устарел, он ничего не может сделать, просто выбросив ошибку. Сервер должен убедиться, что соединение не устарело и обновить его. Он может сделать это во многих отношениях - от возобновления простоя подключений до проверки соединения путем выдачи тестового SQL перед каждым использованием. – OndrejM

+0

«Сервер должен убедиться, что соединение не устарело и обновить его. Оно может сделать это разными способами - от возобновления простоя подключений до проверки соединения путем выдачи тестового SQL перед каждым использованием.«Не могли бы вы уточнить, как обновлять простоя в JTA. – Rashmi

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