Одновременные вызовы веб-службы IIS. NET получают неверный контекст пользователя после возврата из подпрограммы. - PullRequest
0 голосов
/ 07 января 2020

Благодаря обширному ведению журнала, которое я добавил в наш IIS / Servicestack /.NET Web API для решения другой проблемы, я обнаружил некоторые очень тревожные действия при рассмотрении сообщаемой проблемы.

Имейте в виду, что когда Я добавил запись, которую создал GUID при входе в маршрут, чтобы отслеживать процесс вызовов в таблице журнала, выделенной для этого маршрута. Я регистрирую большинство входов и выходов из подпрограмм в маршруте, а также важные путевые точки, и у меня есть вызовы хранимых процедур, которые также записывают в таблицу журналов, все с этим уникальным GUID и другой пользовательской информацией, отметкой времени и т. Д.

Было два разных пользователя, пользователь A и пользователь B, оба выбирали один и тот же маршрут почти в одно и то же время. Маршрут выполняет некоторые манипуляции с базой данных и возвращает значение. Пользователь A прибыл первым, и процесс сделал вызов подпрограммы (R1), который вызвал другую подпрограмму (R2), которая выполнила запрос с command.ExecuteScalar(). Запрос был вызовом хранимой процедуры. Пока выполнялся этот запрос (который занимает менее 1 се c), пользователь B обращается к маршруту, процесс B вызывает подпрограмму R1, которая вызывает подпрограмму R2, которая выполняет запрос с command.ExecuteScalar(). Запросы идентичны в том, что они вызывают одну и ту же хранимую процедуру, но имеют разные пользовательские параметры c.

В этот момент и пользователь A, и пользователь B оба ожидают в R2 своих вызовов на command.ExecuteScalar(), чтобы полный.

Спустя миллисекунды вызов БД пользователя A завершается, поэтому процесс пользователя A выполняет подпрограмму R2 обратно в подпрограмму R1 и немедленно записывает некоторую информацию в таблицу журнала, но записываемая информация является GUID пользователя B (! ). Похоже, что когда R2 завершил и вернул управление R1, контекст R1 для пользователя A теперь стал пользователем B. Процесс пользователя A теперь имеет неправильную локальную среду для R1 (параметры подпрограммы теперь B), поэтому, когда он пытается запросить базу данных, чтобы получить результаты, он терпит неудачу (потому что он использует данные B, а начальный вызов db B еще не завершен). ). Таким образом, процесс пользователя А существует с условием сбоя. Интересно, что когда процесс пользователя A выходит из R1 и возвращается к вызывающей стороне R0, контекст теперь корректен (что подтверждается записями журнала). Таким образом, только контекст R1 для пользователя A был неверным после возврата из R2.

Через миллисекунды вызов базы данных пользователя B завершается, он R2 возвращается обратно в R1 и записывает в журнал свой собственный правильный контекст. Процесс пользователя B может продолжаться без ошибок.

Я пытаюсь определить, где может произойти сбой такого типа, это проблема IIS, проблема Servicetack, проблема. NET, повреждение памяти сервера или что-то другое? У каждого пользователя должен быть свой собственный рабочий поток, как контексты могут быть искажены таким образом?

Если это разовое событие, тогда хорошо, но то, что оно может произойти вообще, очень беспокоит меня.

Есть идеи?

РЕДАКТИРОВАТЬ:

Вот частичный список очищенного журнала, он идет от самого нового к старому.

09, 16:21:45.460, B, 223E72C9-F142-4844-BD6E-C805E4C0EBBA, ...Additional processing
08, 16:21:45.457, B, 223E72C9-F142-4844-BD6E-C805E4C0EBBA, R3 Success
07, 16:21:45.417, B, 223E72C9-F142-4844-BD6E-C805E4C0EBBA, CALL R3
06, 16:21:45.207, B, 223E72C9-F142-4844-BD6E-C805E4C0EBBA, SP Exits
05, 16:21:45.353, A, D4F1AA08-6735-4335-9BB5-62723B2AA2A7, R0 Exit
04, 16:21:45.350, A, D4F1AA08-6735-4335-9BB5-62723B2AA2A7, R0 Fails
03, 16:21:45.283, B, 223E72C9-F142-4844-BD6E-C805E4C0EBBA, R3 Fails (exits R1)
02, 16:21:45.247, B, 223E72C9-F142-4844-BD6E-C805E4C0EBBA, CALL R3
01, 16:21:40.920, A, D4F1AA08-6735-4335-9BB5-62723B2AA2A7, SP Exits

У 01 пользователя A сохраненный про c заканчивается. Строка 02 показывает процесс пользователя B, вызывающий R3, который происходит после завершения хранимой процедуры. Это должен быть пользователь A. Примечание. В строке 04 после того, как R1 возвращает ошибку в R0, контекст для пользователя A. теперь корректен. Строка 06 - это конец хранимой процедуры пользователя B. Строки 07-on - это то, что пользователь B обычно обрабатывает результат.

Строка 02-03 должна была быть данными пользователя A, если бы она была успешной

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