Bezdepbonusu7Программирование: статьи и ответы

Вопрос

В SQL Server CLR Threadsafe

Автор вопроса: u07chОтветов: 4

У меня есть интерфейс в CLR между SQL Server и веб-службами Exchange для синхронизации и отправки электронных писем между приложениями. При тестировании это работает без проблем; мы наблюдаем спорадические проблемы в производственной среде, когда более длительные задачи веб-службы перекрываются.

Мой вопрос очень прост, и я не могу решить, прочитав подробности CLR в MSDN - CLR Thread Safe или не из коробки.

Если нет, то лучший способ сделать вызовы CLR, которые являются потокобезопасными, - это заблокировать мои процедуры или есть менее радикальная альтернатива.


Спасибо за ваши ответы; мы подходим к тому, что это проблема EWS / олицетворения, а не проблема SQL. Мы провели новый набор нагрузочных тестов в нерабочее время в системе, и даже при большой нагрузке (в 1000 раз выше, чем приложение видело до сих пор) мы не видим проблемы с утечкой памяти / многопоточностью, поэтому мы теперь ищем в другом месте. ..

  • Эта ссылка не совсем тот же вопрос, но она может дать некоторую информацию: stackoverflow.com/questions/663124/ dcp 05.08.2010
  • Пожалуйста, ответьте на свой вопрос с некоторыми подробностями о вашем решении и (через два дня) примите этот ответ. 10.08.2010

sql-serverthread-safetysqlclr

Ответы

Ответ 1 · рейтинг 5 · Remus Rusanu

Не используйте внутрипроцессную среду CLR для внешнего подключения, к веб-службам, обмену или чему-то еще. Используйте обычный процесс вне SQL Server. Вы увидите нечто большее, чем просто "спорадические" проблемы: вы исчерпаете пул рабочих процессов для событий CLR, а SQL Server зависнет.

Ответ 2 · рейтинг 3 · Solomon Rutzky

Ответ на самом деле зависит от того, как вы пишете свой код .Net И как вы регистрируете свою сборку. По умолчанию и по общему предпочтению сборки SQLCLR создаются как БЕЗОПАСНЫЕ, что означает, что SQL Server сканирует сборку при ее создании (фактическая инструкция CREATE ASSEMBLY), чтобы определить, соответствует ли она правилам БЕЗОПАСНОЙ сборки. Сборка SAFE не имеет переменных экземпляра, доступных только для чтения. Это означает, что все переменные являются переменными экземпляра, и если вы объявляете статическую переменную, вы должны использовать модификатор "только для чтения". Это гарантирует, что вы не будете обмениваться данными между потоками.

ОДНАКО, вы можете создать статическую переменную в классе и изменить ее, но сборка должна быть создана как НЕБЕЗОПАСНАЯ. Попытка создать его как SAFE выдаст следующую ошибку:

CREATE ASSEMBLY не удалось, так как метод "MethodName" для типа "ClassName" в безопасной сборке "AssemblyName" сохраняется в статическом поле. Сохранение в статическое поле не допускается в безопасных сборках.

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

Ответ 3 · Paul Keister

Основная проблема, с которой вы сталкиваетесь в коде SQL CLR, - нехватка памяти, что приводит к сбросу AppDomain. Это эквивалентно сбою ОС с точки зрения вашего кода. При использовании SQLCLR вы используете отдельный пул памяти, управляемый SQL Server, который намного меньше и менее гибкий, чем вы привыкли. Мне сказали, что команда SQLCLR работает над этой проблемой.

Одно важное замечание: если вы получите сброс SQLCLR AppDomain, это не повлияет на стабильность вашего сервера в других отношениях. Сбой процедуры SQLCLR просто вернет вызывающей стороне ошибку TSQL.

Ответ 4 · u07ch

Проведя много независимых тестов на CLR сейчас (преднамеренно пытаясь заставить его потерпеть неудачу), если ваш код CLR написан правильно - красиво объявите переменные со значениями инициализации, похоже, что CLR является потокобезопасным.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы