Запрос к базе данных зависает при выполнении запроса на выборку для таблицы, над которой работает весенний пакетный процесс - PullRequest
0 голосов
/ 26 января 2019

У меня есть приложение для хранения файлов, которое имеет две службы (служба заданий и служба файлов) в качестве приложений с весенней загрузкой. Когда пользователь загружает файл, в зависимости от типа файла он обрабатывается с помощью весенних пакетных заданий, а его миниатюра и предварительный просмотр создаются с помощью FFMpeg и / или ImageMagick. Затем эти данные записываются в базу данных (которая в настоящее время разрабатывается в Microsoft SQL Server 2017 Developer локально).

Меньшие файлы работали, как и ожидалось, но я хотел протестировать приложение, отправив кучу больших аудио и видео файлов, и начал обновлять страницу файлов, чтобы увидеть, обрабатываются ли файлы. Однако после нескольких обновлений пользовательский интерфейс оставался в состоянии «загрузки» до тех пор, пока не завершилось весеннее пакетное задание, и после этого результаты не будут отображаться, как ожидалось.

Я запустил тот же тест, проверил вкладку сети и заметил, что вызов, который был сделан для получения списка файлов, находился в состоянии «ожидания». Он оставался на этом этапе до тех пор, пока не завершился весь пакетный процесс, и вернулся как успешный (200).

После некоторой отладки на стороне веб-службы я обнаружил, что приложение файловой службы застревает в следующей строке:

List<Asset> allAssets = jdbcTemplate.query("SELECT asset_id, asset_extension, asset_import_date, asset_imported_by_username, asset_name, asset_path, asset_preview_path, asset_thumbnail_path, asset_type FROM assets", new AssetRowMapper()); 

Так что в моем сценарии, когда я обновляю страницу файлов, я пытаюсь получить доступ к таблице ресурсов, поскольку весенние пакетные задания также работают с той же таблицей, чтобы вставлять и обновлять данные, связанные с каждым файлом. Я подумал, что, возможно, запросы вставки и обновления имеют какой-то приоритет и блокируют таблицу из моих запросов select. Поэтому я создал представление из таблицы активов и изменил свой запрос на:

List<Asset> allAssets = jdbcTemplate.query("SELECT asset_id, asset_extension, asset_import_date, asset_imported_by_username, asset_name, asset_path, asset_preview_path, asset_thumbnail_path, asset_type FROM assets_vw", new AssetRowMapper()); 

К сожалению, это не сработало, и я получил тот же результат.

Чтобы увидеть, происходит ли эта проблема со стороны приложения (мой код) или со стороны базы данных, я выполнил тот же тест, но я выполнил тот же запрос вручную через SQL Management Studio в моей базе данных. Интересно, что после нескольких успешных запросов (как я уже видел в пользовательском интерфейсе) я получил тот же результат, что запрос застрял на стадии «выполнения», пока остальные весенние пакетные задания не были завершены.

Так что, похоже, проблема на стороне базы данных.

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

На данный момент я не уверен, что не так с моей базой данных (или моим кодом). Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Возможно, проблема в том, что ваша большая партия вставок выполняется за одну транзакцию. Для этого сервиса, обрабатывающего вставки, я бы проверил код, чтобы убедиться, что это не так. Если это так, и нет необходимости, чтобы все вставки были операцией "все или ничего". Вы можете сделать все вставки для одного файла частью одной транзакции вместо того, чтобы все файлы были частью одной транзакции. Это гарантирует, что READ LOCKS, поступающие из вашего оператора SELECT, будут иметь возможность попасть в очередь и обработаться гораздо более своевременно.

0 голосов
/ 26 января 2019

Я согласен с комментарием @ scsimon о том, что симптомы вызваны блокировкой. SQL Server по умолчанию использует блокировку на уровне изоляции READ COMMITTED, поэтому ваши запросы SELECT (извлечение всех строк), скорее всего, блокируются, когда они встречают строку для выполняемой загрузки, которая еще не была принята.

Рассмотрите возможность включения опции базы данных READ_COMMITTED_SNAPSHOT, чтобы вместо контроля уровня изоляции READ COMMITTED без изменения кода приложения использовалось управление версиями строк. Это жизнеспособное решение, если только ваше приложение не использует блокировку, например, при использовании таблиц SQL Server в качестве очередей. Другие соображения, касающиеся READ_COMMITTED_SNAPSHOT, - это увеличение использования базы данных tempdb (для хранилища версий) и увеличение размера строки на 14 байт.

Я добавлю, что READ_COMMITTED_SNAPSHOT по умолчанию включено в базе данных SQL Azure, но не в предварительных выпусках.

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