При работе с Spring Batch для проекта я столкнулся со следующей проблемой.Проект состоит из:
- базы данных MySQL (mysqld 10.2.13-MariaDB)
- Spring Boot (2.1.1.RELEASE)
- Spring Batch (4.1.0.RELEASE)
- Spring Batch настроен на использование того же источника данных, что и бизнес-логика для JobRepository
Размер пула соединений hikari для источника данных настроен на размериз 4 (который используется по умолчанию при переносе приложения в наш экземпляр CloudFoundry и вводится во время автоматической реконфигурации Spring). Для справки вы можете взглянуть на пример проекта, в котором я создал минимальный проект для воспроизведения проблемы: https://github.com/FlorianSW/spring-batch-connection-issue
Проблема: если у вас есть контроллер, который обрабатывает одно RequestMapping, в котором происходит, по крайней мере, две вещи: контроллер выполняет произвольное действие, повторяя схему базы данных бизнес-модели (например, сохраняя или запрашивая объект избазы данных), а затем запустить задание Spring Batch через вызов JobLauncher # run.Spring Batch настроен на выполнение задач асинхронно с ThreadPoolTaskExecutor с размером пула 1.
Это работает довольно хорошо, если сопоставление запросов выполняется только несколько раз в секунду (примерно 1-3 раза).Однако, если сопоставление запрашивается больше, скажем, 4+ (во время тестирования я использовал 4 и до 20 запросов) синхронизированным образом (при локальном тестировании), тогда запросы попадают в тупик, где некоторые из нихбудет прервана со следующим исключением:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataAccessResourceFailureException: Could not obtain last_insert_id(); nested exception is java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 5001ms.]
Эта проблема может быть уменьшена при увеличении размера пула соединений по крайней мере до 7 (я не знаю, откуда могло бы получиться это число).После перезапуска приложения и выполнения моего тестового кода JavaScript [1] для отправки нескольких запросов я могу легко увеличить количество запросов на выборку до 150, и приложение обработает эти запросы без каких-либо проблем (как и ожидалось).Где, прежде чем увеличивать размер пула, многочисленные запросы сталкиваются с тайм-аутом.
Я не уверен, квалифицируется ли это как ошибка или как Улучшение или что-то еще, и я не уверен, что компонентоднако, документация или что-то в этом роде, я собираюсь решить эту проблему:
Чтобы выяснить, требуется ли Spring Batch вместе с Spring Boot минимальное количество доступных соединений в пуле соединений БД?Если да, то должно ли это упоминаться в документации?Или, если это ошибка, поскольку соединения JDBC, используемые во время обработки запроса, не возвращаются в пул в течение достаточно короткого промежутка времени?
[1]
for (i = 0; i <= 150; i++) {fetch('http://localhost:8080/api/jobs/' + i, {method: 'PUT'})}