2009-03-24 2 views
7

У меня есть ситуация (я догадываюсь, довольно стандартная), где мне нужно выполнить некоторые бизнес-вычисления и создать кучу записей в базе данных. Если что-то пойдет не так, в любой момент мне нужно отбросить все обратно из базы данных. Obviosly Мне нужна сделка. Мой вопрос в том, где я могу реализовать поддержку транзакций. Вот мой примерИспользование транзакций с бизнес-процессами и шаблон репозитория

//BillingServices - This is my billing service layer. called from the UI 
public Result GenerateBill(BillData obj) 
{ 
    //Validate BillData 

    //Create a receivable line item in the receivables ledger 
    BillingRepository.Save(receivableItem); 

    //Update account record to reflect new billing information 
    BillingRepository.Save(accountRecord); 

    //...do a some other stuff 
    BillingRepository.Save(moreStuffInTheDatabase); 
} 

Если какое-либо из обновлений базы данных не удается, мне нужно отбросить остальные и выйти. Должен ли я просто выставить объект Connection через мое хранилище, в котором я могу назвать

Connection.BeginTransaction()

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

Каков правильный подход? Что делать, если мне нужно развернуть репозитории (или это будет плохой дизайн)?

+1

+1, хороший вопрос. –

+0

Надеюсь, я получу хороший ответ =). На самом деле любой ответ на этот момент был бы приятным. – Micah

ответ

5

Я предполагаю, что вы используете .NET здесь. В этом случае вы можете просто обернуть весь раздел кода в using statement с помощью экземпляра TransactionScope и обработать семантику транзакций для вас. Вы просто должны вызвать Complete method в конце:

//BillingServices - This is my billing service layer. called from the UI 
public Result GenerateBill(BillData obj) 
{ 
    // Create the transaction scope, this defaults to Required. 
    using (TransactionScope txScope = new TransactionScope()) 
    { 
      //Validate BillData 

      //Create a receivable line item in the receivables ledger 
      BillingRepository.Save(receivableItem); 

      //Update account record to reflect new billing information 
      BillingRepository.Save(accountRecord); 

      //...do a some other stuff 
      BillingRepository.Save(moreStuffInTheDatabase); 

      // Commit the transaction. 
      txScope.Complete(); 
    } 
} 

Если происходит исключение, это имеет эффект не вызывая Complete, когда блок кода вышел; Dispose method на TransactionScope вызывается реализация IDisposable interface, когда выходит из строя оператор using.

В вызове Dispose он проверяет, завершена ли транзакция (это состояние установлено, когда Complete успешно). Если это состояние не установлено, оно выполняет откат.

Затем вы можете вложить его в другие экземпляры TransactionScope (глубже в стек вызовов в том же потоке), чтобы создавать более крупные транзакции в нескольких хранилищах.

+0

Итак, что я делаю довольно стандартно, и является ли это наиболее распространенным решением? – Micah

+0

@Micah: Предполагая, что вы используете .NET, да, это предпочтительный метод, когда вы хотите охватить транзакцию через несколько методов/объектов/транзакционных репозиториев. – casperOne

+0

Удивительный! Большое спасибо! – Micah

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

  • Нет связанных вопросов^_^