Как уже упоминалось, TransactionScope
- это путь.
Если вы используете SQL Server 2008 и .NET 3.5, я бы изменил конструкцию, чтобы бизнес-объект управлял транзакцией и оставлял открытие и закрытие соединения с уровнем данных.
При включенном пуле подключений вы фактически не будете нести накладные расходы по открытию физического подключения к базе данных, и ваши подключения будут открыты только при выполнении реальной работы. Поскольку (я предположил), у вас SQL Server 2008 с .NET 3.5, ваша транзакция не превратится в распределенную транзакцию (если вы не открываете несколько соединений одновременно), так что вы получаете лучшее из обоих миров.
Тогда вы могли бы написать свой бизнес-объект так:
using (TransactionScope transactionScope = new TransactionScope())
{
DataObject dataObject = new DataObject();
dataObject.UpdateQuantity(...);
ShippingManager shippingManager = new ShippingManager();
shippingManager.ShipOrder(...);
transactionScope.Complete()
}
Это позволяет избежать необходимости передавать строки подключения всем бизнес-объектам и упрощает координацию транзакций.
Обновление
Прелесть System.Transactions заключается в том, что все транзакции управляются для вас независимо от того, какое соединение вы используете. Вы просто объявляете TransactionScope, и весь доступ к базе данных в этом TransactionScope будет происходить с одной транзакцией (если вы не запросите иное с другими настройками TransactionScope).
В прошлом (SQL Server 2005 .NET 2.0), если вы открывали и закрывали соединение, а затем открывали и закрывали другое соединение (даже с той же строкой соединения), то транзакция переводилась из облегченной транзакции в распределенную транзакцию. , Это было нежелательно, поскольку снижается производительность (отсутствует связь с MSDTC и протокол двухфазной фиксации), а MSDTC может быть проблематичным при настройке во многих производственных средах (брандмауэры и безопасность).
В SQL Server 2008 и .NET 3.5 они добавили возможность избежать этого повышения при открытии и закрытии нескольких соединений с одной и той же строкой соединения в одной транзакции. Для действительно хорошего объяснения того, что они видели Расширение облегченных транзакций в SqlClient .
Обновление 2
Транзакции с Oracle 10g будут правильно работать с TransactionScope. И, похоже, ODP.NET поддерживает легкие транзакции (что приятно). К сожалению, я думаю, что переход к распределенной транзакции будет происходить с закрытием и открытием соединений.
Если вы хотите избежать распределенной транзакции, вы можете передать соединение каждому вызову метода / бизнес-объекту. Если вы не хотите передавать соединение, вы можете использовать класс ConnectionScope , который сохраняет соединение открытым в потоке. Альтернативой этому было бы использование Enterprise Application 3.0 (и выше) блока доступа к данным. Блок доступа к данным может обнаружить, что транзакция выполняется, и использовать то же соединение , чтобы избежать распределенной транзакции.