2013-05-11 4 views
3

Модульное программирование - это правильный подход, но иногда это приводит к проблеме, требующей дополнительных усилий и исследований. У меня есть три функции вставки базы данных, например, InsertName(),InsertAddress(),InsertPhoneNo(). Все эти функции должны выполняться, если исключение возникает в любой из функций, никаких изменений в базе данных не будет.Одиночная транзакция по нескольким методам

Что я могу сделать, это объединить все три в одном и использовать sqltransaction.

InsertDetails() 
{ 
using (SqlTransaction sqlTransaction = cn.BeginTransaction()) 
    { 
     using (SqlCommand cm = new SqlCommand()) 
     { 
     cm.Transaction = sqlTransaction; 
     InsertName();//Code to insert name 
     Insertaddress();//code to insert address 
     InsertPhoneNo();//code to insert phone no 
     } 
     sqlTransaction.Commit(); 
    } 

} 

но решение, приведенное выше, противоречит моему модульному подходу. Возможно ли связать несколько функций с одной транзакцией sql без их слияния, если это не лучший способ, который можно достичь.

ответ

5

Просто перейдите в cn и sqlTransaction в функции, тогда функции будут использовать переданные параметры, а не открывать свои собственные соединения.

1

В хорошо спроектированной распределенной архитектуры (упрощено и centeric базы данных), вы будете иметь (в Lest) там слоев и домен объект уровня (Другие слои будут иметь зависимость к Domin entyty ярусе)

интерфейс пользователя
служба
доступ к данным
Common (Domain Entity)

Зависимость между ними сверху вниз, так
пользовательского интерфейс имеет отношение к службе, сервис для доступа к данным и всех слои зависящих домен Entity

Per домен объекта мы будем иметь отдельную услугу, например, если у нас есть Customer Table и Order table мы будем иметь:
CustomerEntity и OrderEntity (объекты сущностей домена)
CustomerService и OrderService (объекты Service слоя)
CustomerDA и CustomerDA (объекты слоя доступа к данным)

Как правило, любой объект DataAccess будет делать Inset, обновление, удаление своей сущности домена и не будет мешать другим объектам. Операция CRUD.
Вторая роль будет заключаться в том, что любой объект службы должен вызвать свой объект доступа к данным энтерита.

Ключевым моментом, который будет отвечать на ваш вопрос здесь:
Service layer objects can call other services, поэтому услуга выборки называется UpdateCustomerNameAndUpdateAllHisOrders (CustomerEntity клиент) // очень длинное имя
может быть реализован в классе CustomerService, концептуально, как это:

UpdateCustomerNameAndUpdateAllHisOrders(CustomerEntity customer) 
{ 
    //StartTransaction(); 
    CustomerDa.Update(customer); 
    var orders = OrderService.GetAllOrders(customer); 
    //Modify Orders logic 
    OrderService.UpdateOrders(orders); 
    //CommiteTransaction(); 
} 

Кстати для целостности данных, транзакция управляется из сервисного слоя
Ответ @Scott Чемберлен будет делать, как это по-своему

Для управления сделками на уровне обслуживания вы можете увидеть here
Spring.Net Framework - хороший образец этого as an aspect.
Надеюсь быть полезным.

3

Зависит от того, как код написан в методах, но вы можете захотеть взглянуть на объект TransactionScope, так что ваш код будет выглядеть следующим образом:

InsertDetails() 
{ 
    using (TransactionScope ts = new TransactionScope()) 
    {  
     InsertName();//Code to insert name 
     Insertaddress();//code to insert address 
     InsertPhoneNo();//code to insert phone no 

     ts.Complete();  
    }  
} 

Больше информации на MSDN здесь:

http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

+0

В качестве примечания - вам нужно посмотреть в коде в своих методах, чтобы убедиться, что это подходит, и обеспечить сохранение транзакции в базе данных и не перенаправить ее в распределенную транзакцию! – Paddy

Смежные вопросы