Сбой пакетной вставки iBatis с ошибками записи в сокет - PullRequest
0 голосов
/ 06 сентября 2011

В последние пару дней я столкнулся с довольно неприятной проблемой.Я пытаюсь улучшить производительность путем пакетной вставки с помощью iBatis.Однако я вижу, что пакетная вставка завершается неудачно с одной из следующих ошибок - java.sql.BatchUpdateException: ошибка ввода-вывода: сбой соединения из-за программного обеспечения: ошибка записи сокета - java.sql.BatchUpdateException: ORA-12161: TNS: внутренняя ошибка: частичные данныеполучено - java.sql.BatchUpdateException: ошибка ввода-вывода: программное обеспечение вызвало прерывание соединения: сбой recv

Подробности настройки приведены ниже - Сервер приложений - Jboss 5.0.1 - iBatis 2.3.4.732.1 - Spring 2.5.6

Код пакетной вставки, который у меня есть, выглядит следующим образом:

    try
    {
        final String finalStatement = statementName;
        int size = parameterList.size();
        int batchSize = 100;

        for(int ii=0; ii < size;)
        {
            int toIndex = ((ii + batchSize) > size ? size : (ii+batchSize));

            final List<Object> subList = parameterList.subList(ii, toIndex);
            ii += batchSize;
            count = getSqlMapClientTemplate().execute(new SqlMapClientCallback() 
            {
                public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException 
                {
                    executor.startBatch();
                    for(Object finalParameterObject : subList)
                    {                   
                        executor.insert(finalStatement, finalParameterObject);
                    }
                    Integer retCount = new Integer(executor.executeBatch());
                    return retCount;
                }
            });                       
        }

. Иногда это работает, а в других случаях происходит сбой с одной из указанных выше ошибок.Мы используем пул соединений, и я убедился, что время ожидания блокировки достаточно велико, хотя я не верю, что это значение вызывает проблему здесь.Я отключил брандмауэр и все еще вижу ту же проблему.Мне кажется, что соединение прерывается базой данных, я прошел журнал предупреждений (мы используем оракул), но не вижу ошибки в этом файле журнала.Похоже, это проблема конфигурации, но я не уверен, что нужно изменить, поскольку я перепробовал все, что мог придумать.Есть ли что-то, чего мне не хватает?

РЕДАКТИРОВАТЬ - если я сделаю размер партии равным 10 в приведенном выше коде (batchSize = 10), то пакетная вставка работает нормально.

1 Ответ

0 голосов
/ 24 августа 2012

не может комментировать, ответ основан на некоторых предположениях:

Используете ли вы ibatis 2.3 или 3.x?Если это 2.3, вы устанавливаете jdbcType как NUMERIC, но вспомогательное поле java - Double / double?Или подобное несоответствие между фактическим типом java и типом jdbc в отображении ibatis?

У меня была похожая проблема взаимоблокировки пакетных сокетов с ibatis 2.3, spring-orm и postgresql.После включения ведения журнала отладки драйвера JDBC Postgresql найдите множество сообщений разбора для одного пакета, который предполагается равным одному.И оказалось, что ibatis устанавливает другой тип jdbc для нулевого значения / не нулевого значения в том же столбце.Основной причиной было то, что отображение ibatis имело числовой jdbcType одного параметра, но соответствующий тип java - Double.

По шагам через ParameterMap # setParameter от ibatis (PreparedStatement, ParameterMapping, Object [], int) вы узнаете, когда значение равно NULL, ibatis будет устанавливать SetNull с jdbcType, считанным из вашего отображения.Когда значение не является нулевым, оно будет использовать typeHandler для установки значения.И typeHandler, если не предоставлен пользовательский обработчик типа, определяется с помощью TypeHandlerFactory # getTypeHandler (Тип класса, String jdbcType).Он управляется типом java, а не jdbcType.

...