Потоки Java остаются заблокированными навсегда при попытке вставить в БД Oracle - PullRequest
2 голосов
/ 27 апреля 2011

У нас есть приложение Java, которое периодически вставляет строки в базу данных Oracle.Это многопоточное приложение.Все темы, за исключением одного, периодически зависают.Мы подумываем обновить драйвер Oracle JDBC, но я чувствую, что он может появиться снова.Просто хотел получить некоторую информацию, если это ошибка с нашим кодом или что-то еще.У меня есть и трассировка стека, и части кода ниже.Мы видим заблокированную периодически в информации потока.Дайте нам некоторую информацию о том, что может быть не так.

---- Код ----

LogEventBatchPreparedStatementUpdater statementUpdater = new LogEventBatchPreparedStatementUpdater(logEvents);

//        _jdbcTemplate.batchUpdate(INSERT_SQL, statementUpdater);
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try
        {
            connection = _dataSource.getConnection();
            connection.setAutoCommit(false);
            preparedStatement = connection.prepareStatement(INSERT_SQL);
            for (int i = 0; i < statementUpdater.getBatchSize(); i++)
            {
                statementUpdater.setValues(preparedStatement, i);
                preparedStatement.addBatch();
            }
            preparedStatement.executeBatch();
            connection.commit();
        }
        catch (SQLException e)
        {
            _Log.error("Error inserting log line batch",e );
        }
        finally
        {
            try
            {
                preparedStatement.close();
                connection.close();
            }
            catch (SQLException e)
            {
                _Log.error("Error inserting log line batch",e );
            }
        }

---- Трассировка стека ----

"Thread-258 " daemon prio=6 tid=0x09437400 nid=0x2300 runnable [0x0f55f000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(Unknown Source)
        at oracle.net.ns.Packet.receive(Unknown Source)
        at oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)
        at oracle.net.ns.NetInputStream.read(Unknown Source)
        at oracle.net.ns.NetInputStream.read(Unknown Source)
        at oracle.net.ns.NetInputStream.read(Unknown Source)
        at oracle.jdbc.ttc7.MAREngine.unmarshalUB1(MAREngine.java:931)
        at oracle.jdbc.ttc7.MAREngine.unmarshalSB1(MAREngine.java:893)
        at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:369)
        at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1891)
        at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:109
3)
        - locked <0x1ce417c0> (a oracle.jdbc.ttc7.TTC7Protocol)
        at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.ja
va:2047)
        at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.jav
a:1940)
        at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePrepare
dStatement.java:3899)
        - locked <0x18930c00> (a oracle.jdbc.driver.OraclePreparedStatement)
        - locked <0x1ce3f9f0> (a oracle.jdbc.driver.OracleConnection)
        at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingSt
atement.java:294)
        at ************.insertLogEventBatch(JdbcL
ogEventBatchDao.java:61)
        at ************.DBLogEventBatchProcessor.processLo
gLineBatch(DBLogEventBatchProcessor.java:30)
        at ************.LogLineBatcher.processLogLineBatch
(LogLineBatcher.java:274)
        at ************.LogLineBatcher.processBatchBasedOn
Time(LogLineBatcher.java:192)
        at ************.LogLineBatcher.manageBatch(LogLine
Batcher.java:178)
        at ************.LogLineBatcher.access$000(LogLineB
atcher.java:24)
        at ************.LogLineBatcher$1.run(LogLineBatche
r.java:152)
        at java.lang.Thread.run(Unknown Source)

1 Ответ

4 голосов
/ 27 апреля 2011

Тот факт, что состояние потока является RUNNABLE и что он пытается прочитать данные из сокета, означает, что он просто ожидает ответа от базы данных.Итак, нужно выяснить, что ожидает сеанс базы данных.Если вы можете определить сеанс в представлении V$SESSION, в столбце EVENT будет указано, что он ожидает.Похоже, что потенциально может быть ожидание блокировки в базе данных.

FYI, где дамп потока говорит "заблокирован", например, locked <0x1ce417c0>, что просто говорит вам, что поток получил блокировку;Я считаю, что шестнадцатеричный код - это идентификатор объекта, для которого удерживается блокировка.

Здесь - это некоторая полезная информация о интерпретации дампов потоков.

...