Как убить активную сессию оракла запущенного из веб приложения на .Net?
Всем привет.
Вводные:
БД: Оракл 11;
Веб приложение: ASP.Net - развернутый на IIS 7;
Соединение через Oracle.DataAccess.
У меня есть система, которая формирует десяток динамических отчетов с большим количеством данных.
Логики в отчетах много и они неплохо оптимизированы, и в целом показывают хорошую скорость выполнения.
Проблема в том, что системой пользуются порядка 15 человек. И каждый из них одновременно открывает по несколько вкладок и запускает формирование запросов, что в свою очередь снижает производительность сервера БД. Далее, половина из них прождав 5-20 минут и не дождавшись появления данных на интерфейсе закрывают вкладку и тут же открывают новую.
В результате, я со стороны БД вижу 50-100 активных сессии запущенных с приложения.
Вопрос:
1. Как только вкладка закрывается не успев получить данные, процедура формирования данных автоматом убивается на стороне БД?
2. Или продолжает выполнение запроса до победного конца, отъедая ресурсы?
3. В случае 2, есть ли возможность узнать какой SID имеет этот процесс и убить его принудительно?
4. Можно ли подкрутить какие-либо настройки в IIS?
Есть подозрение, что дизайн приложения не подходит реалиям использования. Рождается пара вопросв:
Почему юзеры переоткрывают вкладки? Их никто не уведомляет о прогрессе и они переживают, что все сломалось? В этом случае желание перезагрузить вкладку вполне адекватно.
Обязательно ли отдавать ответ в синхронном режиме? Почему бы не присылать им ответ с репортом и ссылкой на скачивание результата по завершению операции? Или в личном кабинете показывать статус операции. Зачем юзеру минуты висеть на коннекте, пока бизнес-логика прочихается?
Не стоит так же забывать, что по умолчанию в ASP.NET сессия - не разделяемый ресурс и пока один запрос ее занявший не отпустит - другие будут ждать, хоть тысячу вкладок открой.
Решение одно, но печальное: перепроектировать приложение, чтобы отчеты формировались асинхронно. Ибо даже если вы выберите какую-либо рекомендацию ниже - процессинг все равно придется отвязать от веб-запроса.
И да, тогда ожидайте кратного прироста скорости для кейса: "один юзер - несколько репортов", ибо они смогут-таки процессится параллельно.
Есть два предложения:
1) Записывать факт начала создание отчета в HttpContext.Session и при обновлении страницы/перехода к отчетам "продолжать" ждать начатого результата.
2) Записывать факт начала создание отчета в HttpContext.Session и из браузера каждые N секунд присылать что пользователь ждет отчета, как только такие сообщения не приходили N*2 секунд убивать соединение/запрос.