Intereting Posts
Как использовать переменную между двумя проектами c # как передать параметр из @ Url.Action в функцию controllerа в asp.net mvc3 Динамическое создание столбцов в RDLC Заменить неправильные слова с помощью Regex Невозможно привязать целевой метод при создании делегатов для свойств Как динамически использовать консольное приложение или приложение Windows Добавление пользовательских атрибутов в classы C # с использованием Roslyn Извлеките только правое большинство n букв из строки Изменение раскладки клавиатуры из кода C # с помощью .NET 4.5.2 Вставка базы данных в атрибут проверки с ASP MVC и Castle Windsor Как найти доступные COM-порты? VS2005 C # Программно изменить строку подключения, содержащуюся в app.config Почему в .NET есть 5 версий таймерных classов? Как использовать automapper для сопоставления набора данных с несколькими таблицами asp.net mvc razor дополнительное пространство

Является ли SqlConnection / SqlCommand streamом безопасным?

В настоящее время я создаю веб-службу WCF.

В рамках своей работы, к сожалению, потребуется сделать довольно интенсивные вычисления, однако эти вычисления, к счастью, могут быть разделены между вызовами веб-службы. По сути – нам нужно только делать вычисления один раз, и все последующие вызовы могут получить выгоду.

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

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

Однако есть одна загвоздка – мы используем SqlConnection и SqlCommand для связи с нашим бэкэнд, и я не уверен, могу ли я считать, что они являются streamобезопасными?

EDIT: Я должен пояснить, что Commands / Connections всегда являются локальными для метода. Мы говорим образец в духе:

using sqlConn = new SqlConnection(...) { try { sqlConn.Open() } catch () { throw new FaultException(); } var cmd = new SqlCommand("Some SQL", sqlConn); var reader = cmd.ExecuteReader(); //Read the stuff reader.Close(); //Return something } 

END EDIT

Я просмотрел class SqlCommand в MSDN: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.aspx, который гласит: «Все публичные статические (Shared in Visual Basic) члены этого тип является streamобезопасным. Любые члены экземпляра не гарантируют безопасность streamов ».

Я правильно интерпретирую это, думая, что это означает, что MS не гарантирует, что SqlCommand работает в многопоточном сценарии?

Если это не так, существует ли альтернатива streamу?

Да, я мог бы просто заблокировать все методы доступа к базе данных в моем веб-сервисе, но а) это уродливо и б), если это не обязательно, я бы предпочел, чтобы мне не приходилось 🙂

Приветствую вас!

Я правильно интерпретирую это, думая, что это означает, что MS не гарантирует, что SqlCommand работает в многопоточном сценарии?

Он отлично работает в многопоточном сценарии, если вы используете его правильно.

Если несколько streamов пытаются использовать SAME SqlCommand, как вы думаете, что произойдет? Как это могло бы работать?

но если разные streamи, использующие разные соединения, вызывают разные команды в одной и той же базе данных, нет проблем.

Заметки о безопасности streamов на MSDN действительно сломаны и плохо сформулированы и должны быть написаны кем-то, кто не знал, что такое безопасность streamов.

То, что они пытаются сказать с этим сообщением (которое закреплено на 99,9% classов и функций, задокументированных в MSDN), заключается в том, что «любой статический метод этого типа можно безопасно вызывать одновременно несколькими streamами. экземпляр не гарантированно безопасен, если он вызывается одновременно несколькими streamами, но доступ к одному и тому же элементу на разных объектах совершенно прекрасен ».

Я не уверен на 100%, что вы пытаетесь сделать одновременно с SqlCommand, но независимо от внутренней безопасности streamов, у вас наверняка возникнут проблемы, потому что использование SqlCommand требует, чтобы он поддерживал состояние, например

 SqlCommand cmd = myConnection.CreateCommand(); cmd.CommandText = "......"; cmd.Parameters.Add(.....); cmd.ExecuteNonQuery(); 

Если вы пытаетесь использовать одну и ту же команду через несколько streamов, вам придется заблокировать что-то, пока вы ее используете.

Что касается SqlConnection, это позволит вам одновременно открывать один запрос, поэтому, если вы используете DataReaders, вам придется что-то заблокировать. Использование нескольких соединений / команд важно, если вы хотите запускать несколько элементов одновременно.

Я также не уверен, что вы имеете в виду, когда говорите, что WCF не имеет общего состояния приложения – это не обязательно так, это будет зависеть от того, как вы принимаете ваше приложение WCF. Если это служба WCF, размещенная в IIS с параметром aspNetCompatibilityEnabled="true" , у вас все еще есть объект Application, который вы получите на веб-сайте. Существуют и другие варианты, если вы также не используете aspNetCompatibility.

просто используйте соединение и команду из knly one thread и не заботитесь об уровне нити на уровне приложений. sql-сервер достаточно хорош, чтобы обрабатывать параллелизм для вас, без необходимости блокировки кода. Пул соединений .Net также может быстро найти действительные соединения.

Я не говорю, что весь слой WCF, который вы делаете, не должен заботиться о streamах, но его DAL должен работать, полагаясь на блокировки db, а не на блокировки .net.