2009-03-24 29 views
7

Tôi có một tình huống (tôi đoán là khá chuẩn), nơi tôi cần thực hiện một số phép tính kinh doanh và tạo một loạt các bản ghi trong cơ sở dữ liệu. Nếu có bất cứ điều gì xảy ra bất cứ lúc nào tôi cần phải cuộn mọi thứ trở lại từ cơ sở dữ liệu. Tôi cần một số loại giao dịch. Câu hỏi của tôi là nơi nào tôi thực hiện hỗ trợ giao dịch. Dưới đây là ví dụ của tôiSử dụng các giao dịch với quy trình nghiệp vụ và mẫu Kho lưu trữ

//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); 
} 

Nếu có bất kỳ cập nhật nào cho cơ sở dữ liệu không, tôi cần phải cuộn các bản cập nhật khác lại và thoát ra. Tôi chỉ tiếp xúc với một đối tượng Connection qua Repository của tôi trong đó tôi có thể gọi

Connection.BeginTransaction()

hay tôi làm tôi chỉ xác nhận trong lớp dịch vụ và chỉ cần gọi một phương pháp trong kho đó lưu tất cả các đối tượng và xử lý giao dịch? Điều này dường như không đúng với tôi. Nó có vẻ như nó sẽ buộc tôi phải đưa vào logic kinh doanh nhiều trong lớp dữ liệu.

Cách tiếp cận phù hợp là gì? Điều gì sẽ xảy ra nếu tôi cần mở rộng kho (hoặc đó có phải là thiết kế xấu) không?

+1

+1, câu hỏi hay. –

+0

Hy vọng tôi sẽ nhận được câu trả lời tốt =). Trên thực tế bất kỳ câu trả lời tại thời điểm này sẽ là tốt đẹp – Micah

Trả lời

5

Tôi giả định rằng bạn đang sử dụng .NET tại đây. Trong trường hợp đó, bạn có thể chỉ cần quấn toàn bộ phần mã trong một using statement với một cá thể TransactionScope và nó sẽ xử lý ngữ nghĩa giao dịch cho bạn. Bạn chỉ cần phải gọi Complete method ở cuối:

//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(); 
    } 
} 

Nếu một ngoại lệ xảy ra, điều này có tác dụng không gọi Complete khi khối mã được thoát; số Dispose method khi triển khai TransactionScope của IDisposable interface được gọi khi phạm vi của câu lệnh using bị thoát.

Trong cuộc gọi Dispose, séc sẽ kiểm tra xem giao dịch đã hoàn tất chưa (trạng thái này được đặt khi Complete thành công). Nếu trạng thái đó không được thiết lập, nó sẽ thực hiện khôi phục.

Sau đó, bạn có thể lồng tổ chức này trong các trường hợp TransactionScope khác (sâu hơn trong ngăn xếp cuộc gọi của bạn trên cùng một chuỗi) để tạo giao dịch lớn hơn trên nhiều vị trí lưu trữ.

+0

Vì vậy, là những gì tôi đang làm khá chuẩn, và đây có phải là giải pháp phổ biến nhất? – Micah

+0

@Micah: Giả sử bạn đang sử dụng .NET, vâng, đây là phương thức ưa thích khi bạn muốn mở rộng một giao dịch trên nhiều phương thức/đối tượng/kho lưu trữ giao dịch. – casperOne

+0

Tuyệt vời! Cảm ơn rất nhiều! – Micah

Các vấn đề liên quan