2017-02-13 4 views
2

У меня есть приложение java java java jQuery, которое использует многопоточность, которая использует OJDBC5 как сообщение для oracle 11g (11.2.0.3). После проверки содержимого потока каждый поток вызывает вызывающий оператор, который должен быть подготовлен, затем выполняет вставку данных в таблицу. Теперь при инициализации есть Total JDBC 20 Connections. Некоторое время у него действительно нет проблем.Connection Pool висит с многопоточной программой java

Но недавно появился экземпляр, где он просто повесился во время выполнения вызываемого оператора в БД.

2017-02-06 13:03:39,855 [Thread-1] INFO QCCOM_SocketWorker run - Worker thread launched. 
2017-02-06 13:03:39,856 [Thread-1] INFO QCCOM_Socket recvMessage 
2017-02-06 13:03:39,856 [Thread-1] INFO QCCOM_SocketWorker recvRequest 
2017-02-06 13:03:39,856 [Thread-1] INFO ProcessHandler invoke 
2017-02-06 13:03:39,856 [pool-1-thread-1] INFO HandlerValidator validateRequest 
2017-02-06 13:03:39,857 [pool-1-thread-1] INFO ProcessHandler process - Processing request... 
2017-02-06 13:03:39,857 [pool-2-thread-1] INFO JDBCHelper call - Atempting to retrieve connection. 
2017-02-06 13:03:39,857 [pool-2-thread-1] INFO JDBCHelper call - Connection successfully retrieved 
2017-02-06 13:03:39,857 [pool-1-thread-1] INFO JDBCHelper getConnection - Conn : [email protected] 
2017-02-06 13:03:39,858 [pool-1-thread-1] INFO JDBCServiceImpl insertBP - Calling insert transaction stored procedure.. 
2017-02-06 13:03:43,856 [Thread-1] INFO ProcessHandler invoke - Worker Thread Timed out 
2017-02-06 13:03:43,857 [Thread-1] DEBUG ProcessHandler invoke - [java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:226), java.util.concurrent.FutureTask.get(FutureTask.java:100), ....ProcessHandler.invoke(ProcessHandler.java:114), com.qcom.qcm.qccom.QCCOM_SocketWorker.dispatch(QCCOM_SocketWorker.java:88), com.qcom.qcm.qccom.QCCOM_SocketWorker.run(QCCOM_SocketWorker.java:126)] 
2017-02-06 13:03:43,857 [Thread-1] INFO QCCOM_SocketWorker run - Worker thread shutdown. 
2017-02-06 13:03:55,661 [pool-1-thread-1] INFO JDBCServiceImpl insertBP - Callable Statement successfully closed! 
2017-02-06 13:03:55,661 [pool-1-thread-1] INFO JDBCServiceImpl insertBP - Connection successfully closed! 
2017-02-06 13:03:55,662 [pool-1-thread-1] INFO ProcessHandler process - Connection successfully closed! 

Обычно транзакция происходит менее чем за 200 мс.

2017-02-06 13: 03: 39858 [бассейн-1-токарно-1] INFO JDBCServiceImpl insertBP - Calling вставка транзакций хранимая процедура ..

Но в случае, выше у нас висят на исполнение вставки.

См. Код ниже (JDBCServiceImpl insertBP).

public synchronized void insertBP(String A, BigDecimal Num, Date Date) throws SQLException{ 
    CallableStatement cs = null; 
    logger.info("Calling insert transaction stored procedure.."); 
    try{ 
     cs = (CallableStatement) conn.prepareCall("{"+sql+"}"); 
     cs.setString(1, tnxType); 
     cs.setBigDecimal(2, Num); 
     cs.setTimestamp(3, new Timestamp(Date.getTime())); 

     cs.execute(); 
    } catch (SQLException sqlEx){   
     String strMessageContents = StringUtil.getFailedMessageContents(A, Num, Date); 
     String strErrorMessage = "Failed to insert "; 
     logger.fatal(strErrorMessage); 
     aUtil.emailFatal; 
     throw sqlEx; 
    } finally { 
     if (null!=cs){ 
      cs.close(); 
      logger.info("Callable Statement successfully closed!"); 
     } 
     if (null!=conn){ 
      conn.close(); 
      logger.info("Connection successfully closed!"); 
     } 
    } 
} 

Как-то он висит на cs.execute ... Затем таймаут рабочего потока приходит и убивает всю транзакцию, но почему-то не убивает уже начатое вызываемое заявление.

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

2017-02-06 13: 03: 55,661 [pool-1-thread-1] INFO JDBCServiceImpl insertBP - Вызываемое заявление успешно закрыто!

код выглядит следующим образом

if (Util.IsOffline){ 
    logger.info("App is Offline attempting to reestablish connection."); 
    Util.destroyHelper(); 
    logger.info("Previous Connection Pool Destroyed..."); 
    logger.info("Reinitializing Connection Pool ..."); 
    try { 
     AppJDBCHelper helper = AppJDBCHelper.getInstance(); 
     if (null != helper){ 
      logger.info("Connected to Schema: "+helper.getSchema()); 
      logger.info("Connection Pool initialized ..."); 
      Util.IsOffline = false; 
      logger.info("App has reestablished connection."); 
     } 
     if (null == helper){ 
      logger.fatal("Failed to get database connection pool ..."); 
      Util.destroyHelper(); 
     } 
    } catch (SQLException e){ 
     logger.fatal("Failed to connect to database ..."); 
     logger.debug(Arrays.toString(e.getStackTrace())); 
     System.out.println(" \n >>> ERROR: Failed to connect to database ..."); 
     Util.destroyHelper(); 
    } 
} 

Дополнительный код для Util

public void destroyHelper(){ 
    AppJDBCHelper helper = null; 
    try { 
     helper = AppJDBCHelper.getInstance(); 
     helper.destroy(); 
    } catch (SQLException e) { 
     logger.fatal(e); 
     logger.debug(Arrays.toString(e.getStackTrace())); 
    }  
} 

Дополнительный код для AppJDBCHelper

public void destroy() throws SQLException{ 
    DBConnectionPool pool = new DBConnectionPoolImpl(); 
    pool.closeConnectionPool(ods); 
    helper = null; 
    logger.info("AppJDBCHelper destroy() success..."); 
} 

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

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

+2

С апреля 2009 года в JVM зафиксированы сотни, если не тысячи ошибок. Если вы получаете странное поведение, вам может потребоваться протестировать его с помощью более поздней версии JVM или даже последней версии Java 5.0, выпущенной позже, год. –

+0

Да, я понял, что предложил это, но клиент все еще не хочет обновлять версию Java. –

+0

Понял. Можете ли вы придумать работу, если исправление не кажется очевидным? –

ответ

0

Один из возможных подходов - пойти снизу вверх и сначала проверить, были ли проблемы в базе данных. Если вы на Oracle 11g, есть хорошие изменения вы также иметь лицензию ASH

Проверьте базу данных (или обратитесь к администратору базы данных) с помощью следующего запроса, где вы параметризовать времени intrval и вашего пула соединений DBUser. (Если проблема была в прошлом, перейдите в таблицу dba_hist_active_sess_history, которая содержит более длительный интервал времени.

select 
SAMPLE_TIME, SQL_EXEC_ID, SESSION_ID, SESSION_SERIAL#, SQL_ID, TOP_LEVEL_SQL_ID, SQL_OPNAME, 
PLSQL_ENTRY_OBJECT_ID, EVENT, BLOCKING_SESSION_STATUS, BLOCKING_SESSION, BLOCKING_SESSION_SERIAL# 
select * from v$active_session_history 
where sample_time between to_date('15022017 214500','ddmmyyyy hh24miss') and to_date('15022017 215000','ddmmyyyy hh24miss') 
and USER_ID in (select user_id from dba_users where username = '<your user name>') 
order by session_id, SESSION_SERIAL#,SAMPLE_TIME; 

Вот пример вывод, имитируя INSERT заблокирована блокировкой таблицы.

SAMPLE_TIME     SESSION_ID SESSION_SERIAL# SQL_ID  TOP_LEVEL_SQL_ID SQL_OPNAME PLSQL_ENTRY_OBJECT_ID EVENT     BLOCKING_SESSION_STATUS BLOCKING_SESSION BLOCKING_SESSION_SERIAL# 
--------------------------- ---------- --------------- ------------- ---------------- ----------- --------------------- ----------------------- ----------------------- ---------------- ------------------------ 
15.02.17 21:45:20,669000000   11   10976 gr2assvfzr2v7 6j87w7zmmzpsk INSERT      154744 enq: TM - contention VALID         13      4283 
15.02.17 21:45:21,683000000   11   10976 gr2assvfzr2v7 6j87w7zmmzpsk INSERT      154744 enq: TM - contention VALID         13      4283 
15.02.17 21:45:22,682000000   11   10976 gr2assvfzr2v7 6j87w7zmmzpsk INSERT      154744 enq: TM - contention VALID         13      4283 
15.02.17 21:45:23,680000000   11   10976 gr2assvfzr2v7 6j87w7zmmzpsk INSERT      154744 enq: TM - contention VALID         13      4283 
15.02.17 21:45:24,679000000   11   10976 gr2assvfzr2v7 6j87w7zmmzpsk INSERT      154744 enq: TM - contention VALID         13      4283 
15.02.17 21:45:25,693000000   11   10976 gr2assvfzr2v7 6j87w7zmmzpsk INSERT      154744 enq: TM - contention VALID         13      4283 
15.02.17 21:45:26,691000000   11   10976 gr2assvfzr2v7 6j87w7zmmzpsk INSERT      154744 enq: TM - contention VALID         13      4283 
15.02.17 21:45:27,689000000   11   10976 gr2assvfzr2v7 6j87w7zmmzpsk INSERT      154744 enq: TM - contention VALID         13      4283 

inportant informaton является отметкой о времени, идентификация сеанса, операция SQL (вы ожидаете INSERT) и EVENT. В моем примере вы видите EVENT enq: TM - contention, что означает, что таблица заблокирована и сеанс не может выполнить вставку. Конечно, вы можете увидеть другое событие - проверьте проблему Oracle documentation. Наконец, вы видите статус блокировки и блокирующий сеанс, который может предоставить решение, почему возникла проблема.

Если вы не видите каких-либо подозрительных доказательств в базе данных (состояния блокировки или ожидания), выполните проверку и проверку журналов вашего приложения.

+0

Благодарим за предложение и попрошу DBA предоставить подробную информацию. Но, как я помню, они сказали, что замков нет. будет ли отображаться любые другие проблемы, которые могут присутствовать, кроме блокировки? –

+0

@Kyle ASH ** предназначен для устранения таких проблем **. Если это случится в прошлом. Вы видите периодический снимок всех активных сеансов. Это не ограничивается блокировкой, вы видите, что сеансы хрустят CPU или ждут ввода-вывода. Проверьте документацию, поиграйте с ней в своей БД разработки и * желательно * запросить доступ к продуктивной БД. Хороший замок! –

+0

Привет и спасибо за головы. В любом случае я попросил наш DBA запустить выбранные запросы, и он выдал «никаких строк». Кажется, в течение этого времени не было никаких проблем или оно не было полностью записано. Любые другие предложения, которые я могу проверить, когда команда DB проверяет это? –

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