Когда вы создаете TransactionScope, все соединения, которые вы открываете, пока TransactionScope существует, автоматически присоединяются к транзакции (они «автоматически зачисляются»). Так что вам не нужно передавать строки подключения.
Возможно, вы захотите, когда SQL Server видит разные транзакции (даже если они все содержатся в одной транзакции DTC), он не разделяет блокировки между ними. Если вы открываете слишком много соединений и много читаете и пишете, вы попадаете в тупик.
Почему бы не поместить активное соединение в какое-то глобальное место и использовать его?
Еще немного информации после некоторого исследования. Прочитайте это: TransactionScope автоматически переходит в MSDTC на некоторых машинах? .
Если вы используете SQL Server 2008 (и, вероятно, 2012, но не какую-либо другую базу данных), некоторые закулисные действия происходят за кулисами, и если вы открываете два соединения SQL , одно за другим , они собираются объединиться в одну транзакцию SQL, и у вас не будет проблем с блокировкой.
Однако , если вы используете другую базу данных или можете одновременно открыть два соединения, вы получите транзакцию DTC, что означает, что SQL Server не будет правильно управлять блокировками, и вы можете столкнуться с очень неприятные и неожиданные тупики.
Хотя легко убедиться, что вы работаете только на SQL Server 2008, убедиться, что вы не открыли два соединения одновременно, немного сложнее. Это очень легко забыть и сделать что-то вроде этого:
class MyPersistentObject
{
public void Persist()
{
using(SQLConnection conn=...)
{
conn.Open()
WriteOurStuff()
foreach(var child in this.PersistedChildren)
child.Persist()
WriteLogMessage()
}
}
}
Если дочерний метод Persist открывает другое соединение, ваша транзакция преобразуется в транзакцию DTC, и вы сталкиваетесь с потенциальными проблемами блокировки.
Поэтому я все еще предлагаю поддерживать соединение в одном месте и использовать его через свой DAL. Это не должна быть простая глобальная статическая переменная, вы можете создать простой класс ConnectionManager со свойством ConnectionManager.Current, которое будет содержать текущее соединение. Сделайте ConnectionManager.Current как [ThreadStatic], и вы решите большинство своих потенциальных проблем. Именно так работает TransactionScope за кулисами.