Như đã đề cập bởi những người khác, TransactionScope
là cách để thực hiện.
Nếu bạn đang sử dụng SQL Server 2008 và .NET 3.5, tôi sẽ sửa đổi thiết kế để có đối tượng kinh doanh kiểm soát giao dịch và để mở và đóng kết nối với lớp dữ liệu.
Với tính năng kết nối kết nối, bạn sẽ không thực sự phải gánh chịu chi phí mở kết nối cơ sở dữ liệu vật lý và kết nối của bạn sẽ chỉ mở khi thực hiện công việc thực tế. Kể từ khi (tôi giả định) bạn có SQL Server 2008 with .NET 3.5 your transaction will not escalate to a distributed transaction (trừ khi bạn mở nhiều kết nối cùng một lúc) để bạn tận dụng tối đa cả hai thế giới.
Sau đó, bạn có thể viết đối tượng doanh nghiệp của bạn như thế này:
using (TransactionScope transactionScope = new TransactionScope())
{
DataObject dataObject = new DataObject();
dataObject.UpdateQuantity(...);
ShippingManager shippingManager = new ShippingManager();
shippingManager.ShipOrder(...);
transactionScope.Complete()
}
này tránh được việc phải vượt qua chuỗi kết nối xung quanh để tất cả các đối tượng kinh doanh và làm việc điều phối các giao dịch dễ dàng.
Cập nhật
Vẻ đẹp của System.Transactions là tất cả các giao dịch được quản lý cho bạn không phụ thuộc vào kết nối mà bạn đang sử dụng. Bạn chỉ cần khai báo một TransactionScope và tất cả các truy cập cơ sở dữ liệu trong TransactionScope đó sẽ xảy ra với một giao dịch duy nhất (trừ khi bạn yêu cầu khác với các thiết lập TransactionScope khác).
Trong quá khứ (SQL Server 2005 .NET 2.0), nếu bạn đã mở và đóng kết nối rồi mở và đóng kết nối khác (ngay cả với cùng chuỗi kết nối) thì giao dịch được đẩy từ Giao dịch nhẹ đến Phân phối Giao dịch. Điều này là không mong muốn bởi vì hiệu suất bị (thông tin liên lạc với MSDTC là quá trình và giao thức cam kết hai pha) và MSDTC có thể là một nỗi đau để cấu hình trong nhiều môi trường sản xuất (tường lửa và bảo mật).
Với SQL Server 2008 và .NET 3.5, họ đã thêm khả năng tránh quảng cáo này khi mở và đóng nhiều kết nối với cùng một chuỗi kết nối trong một giao dịch. Để có giải thích thực sự tốt về những gì họ đã thấy, hãy xem Extending Lightweight Transactions in SqlClient.
Cập nhật 2
Giao dịch với Oracle 10g sẽ hoạt động đúng với TransactionScope. Và có vẻ như ODP.NET supports Lightweight Transactions (điều này rất hay). Thật không may, tôi nghĩ rằng việc quảng cáo cho một giao dịch phân phối sẽ xảy ra với việc đóng và mở các kết nối.
Nếu bạn muốn tránh một giao dịch phân tán, bạn có thể chuyển kết nối đến mọi cuộc gọi phương thức/Đối tượng kinh doanh. Nếu bạn không muốn truyền kết nối, bạn có thể sử dụng ConnectionScope class để giữ kết nối mở trên chuỗi. Một thay thế cho điều đó sẽ là sử dụng Enterprise Library 3.0 (và cao hơn) Khối ứng dụng truy cập dữ liệu. Data Access Block can detect that a transaction is in progress and use the same connection để tránh giao dịch được phân phối.
Mặc dù 'TransactionScope' * là * lớp để sử dụng ở đây, với thiết kế hiện tại của OP nó sẽ dẫn đến một giao dịch phân tán hoặc có thể là ngoại lệ nếu MSDTC bị tắt hoặc bị khóa. Đó là * có lẽ * không phải là kết quả mong muốn. – Aaronaught
@Aaronaught, với SQL Server 2008 và .NET 3.5 giao dịch sẽ không được quảng bá cho một giao dịch phân tán (đối với thiết kế hiện tại). –
@Tuzo: Đúng, với SQL Server 2008, bạn có thể gian lận vấn đề đa kết nối ** NẾU ** tất cả các kết nối đến cùng một cơ sở dữ liệu ** và ** chỉ có một lần mở cùng một lúc. Nó vẫn là một thực tế khá đáng ngờ, đặc biệt là khi thiết kế thay thế được dễ dàng hơn để xây dựng/duy trì anyway. – Aaronaught