2009-05-22 2 views
5

Хорошо ли иметь один общий объект SqlConnection в приложении .NET для использования для всех подключений к базе данных или у вас есть отдельный каждый раз при обращении к базе данных?Shared SqlConnection

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

Существует уже открытый DataReader, связанный с этой Командой, который должен быть закрыт первым.

ответ

4

У вас должен быть отдельный действительно. Повторное использование соединений обрабатывается с помощью connection pooling. Второй вопрос, как и другие, сказал, вероятно, можно решить, включив MARS.

0

Если вы используете SQL Server 2000, this может ответить на ваш вопрос.

Получается, что выигрышный ответ выглядит следующим образом: «Это связано с изменением настроек по умолчанию для MAR. Раньше оно было включено по умолчанию, и мы поменяли его по умолчанию по умолчанию RC1. Поэтому просто измените строку подключения на добавьте его обратно (добавьте MultipleActiveResultSets = True в строку подключения). "

1

Это может быть dup from here; короче говоря, поддерживать связь в краткосрочной перспективе и локально в большинстве случаев. Повторите считыватель данных; возможно включить MARS?

1

Хотя для одного потока он может лучше работать с одним объектом SqlConnection, он ставит требования к ценному ресурсу, который является вашим сервером базы данных, подключаясь к соединению и, следовательно, к ресурсам сервера db, дольше, чем нужно.

Лучше создать экземпляр SqlConnection как можно более короткий период времени. Пул соединений уменьшает большую часть затрат на настройку соединения и обеспечивает наиболее эффективное использование ресурсов базы данных.

3

Эта ошибка не имеет абсолютно никакого отношения к аутентификации. Вы повторно используете соединение с середины, прежде чем закрываете свой SqlDataReader, возвращенный из ExecuteReader(). Это запрещено. Вы должны проверить свой код и устранить свою проблему. Существуют альтернативы использованию MARS (multiple active record sets), но я бы сильно отговаривал это.

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

+0

Если вы говорите «не используйте MARS» - у вас есть какие-то конкретные причины? Из любопытства ... –

+0

http://blogs.msdn.com/sqlnativeclient/archive/2006/09/27/774290.aspx обсуждает некоторые из негативов с использованием MARS – RichardOD

+2

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

2

Ваша проблема заключается в том, что вы пытаетесь использовать соединение, которое в настоящее время используется SqlDataReader. Вы не можете этого сделать. Когда вы используете SqlDataReader, вы должны закрыть его, прежде чем повторно использовать используемое соединение. Я предлагаю вам создать другое соединение каждый раз, когда вы обращаетесь к БД (в любое время, а не только с SqlDataReaders). Если у вас включен пул, сама каркас (или это SqlServer?) Будет использовать повторно соединения, когда это возможно.

Если вам нужно получить доступ к БД последовательно, допустим, вы сделаете выбор, затем выберите другой вариант, а затем обновление, вы можете повторно использовать соединение (я имею в виду один и тот же экземпляр SqlConnection), но если вам нужно получить доступ DB при чтении из SqlDataReader, тогда вам понадобятся два разных соединения.

Конечно, вы должны иметь в виду проблемы параллелизма.Если вы используете транзакции, то некоторые записи могут быть заблокированы во время определенных операций, а когда вы используете SqlDataReader параллельно с другими запросами, вы должны установить уровень изоляции на уровень, который не путается с остальными запросами.