Весенний пакет JdbcCursorItemReader вызывает нехватку памяти - PullRequest
1 голос
/ 28 марта 2019

Я использую Spring Batch Framework для переноса данных. Читатель, который я использую, - JdbcCursorItemReader. Я установил размер фрагмента равным 500 и установил размер выборки считывателя равным 1000. Но при запуске службы с использованием пакетной пружины кажется, что все данные считываются один раз в памяти и заканчиваются из памяти. затем бросить память не хватает вопроса. Ниже, как я определяю читателя:

   private JdbcCursorItemReader<Map<String, Object>> buildItemReader(final DataSource dataSource, String tableName,String tenant) {
        String tenantName = tenantHelper.determineTenant(tableName);
        JdbcCursorItemReader<Map<String, Object>> itemReader = new JdbcCursorItemReader<>();
        itemReader.setDataSource(dataSource);
        itemReader.setSql("select * from " + tableName + " where " + tenantName + " ='" + tenant + "'");
        itemReader.setRowMapper(new ColumnMapRowMapper());
        itemReader.setFetchSize(100);
        return itemReader;
    }

Более того, из весеннего пакетного документа здесь мы сможем избежать проблемы с памятью, используя jdbcCursorItemReader

Ответы [ 3 ]

2 голосов
/ 28 марта 2019

Вы можете попробовать использовать JdbcPagingItemReader вместо JdbcCursorItemReader, где размер страницы можно задать при настройке

1 голос
/ 16 апреля 2019

Понял это с помощью jdbcPagingItemReader. Основная причина, по которой устройство чтения курсоров потребляет огромную память, заключается в том, что он просто считывает все данные в память и затем обрабатывает их, что будет рассматриваться JVM как большой объект, и он будет непосредственно размещен в старом поколении, пока весь процесс закончен, его невозможно собрать.

1 голос
/ 28 марта 2019

Я просто запутался, почему он использует всю память и загружает все данные в память

Согласно документации Postgresql , драйвер собирает все результаты запроса сразу.

Вероятно, вы можете попытаться отключить курсор, установив размер выборки равным 0. Существуют и другие ограничения, описанные в вышеупомянутом документе, пожалуйста, убедитесь, что ваш код соответствует всем им. Просто для справки, это похоже на то, что может случиться с MySQL, где размер выборки должен быть установлен на Integer.MIN_VALUE для потоковой передачи результатов (см. здесь и здесь ).

Надеюсь, это поможет.

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