2009-02-12 36 views
69

là gì sự khác biệt giữa mô hình giao dịch cổ điển trong LINQ to SQL như:TransactionScope vs giao dịch trong LINQ to SQL

using(var context = Domain.Instance.GetContext()) 
{ 
    try 
    { 
     context.Connection.Open(); 
     context.Transaction = context.Connection.BeginTransaction(); 
     /*code*/ 
     context.Transaction.Commit(); 
    } 
    catch 
    { 
     context.Transaction.Rollback(); 
    }   
} 

vs đối tượng TransactionScope

using (var context = Domain.Instance.GetContext()) 
using (var scope = new TransactionScope()) 
{ 
    try 
    { 
     /*code*/ 
     scope.Complete(); 
    } 
    catch 
    { 
    } 
} 

Trả lời

34

Linq2SQL sẽ sử dụng giao dịch ngầm định. Nếu tất cả các cập nhật của bạn được thực hiện trong một lần gửi, bạn có thể không cần phải tự xử lý giao dịch.

Từ các tài liệu (tôi nhấn mạnh):

Khi bạn gọi SubmitChanges, LINQ to SQL sẽ kiểm tra để xem liệu cuộc gọi là trong phạm vi của một giao dịch hoặc nếu tài sản giao dịch (IDbTransaction) được thiết lập để giao dịch cục bộ do người dùng bắt đầu. Nếu nó không tìm thấy giao dịch, LINQ to SQL bắt đầu một giao dịch cục bộ (IDbTransaction) và sử dụng nó để thực thi các lệnh SQL được tạo ra. Khi tất cả các lệnh SQL đã được hoàn tất thành công, LINQ to SQL cam kết giao dịch và trả về cục bộ.

+10

Nếu bạn cần gửi một cái gì đó với tính chất chu kỳ (phổ biến), bạn nhấn một lỗi trong LINQ to SQL yêu cầu bạn xóa một phần của mỗi tham chiếu 2 chiều, gửi, sửa các tham chiếu 2 chiều và gửi lại. Bạn cần phải quấn tất cả điều này trong giao dịch của riêng bạn để làm như vậy. Đó là một nhu cầu phổ biến, do đó, "Đừng lo lắng về nó" không phải là câu trả lời tốt nhất. –

4

Tôi tin rằng họ là về cơ bản giống nhau rằng lớp TransactionScope sẽ giao diện với kết nối ADO.NET bên dưới để tạo và cam kết hoặc khôi phục giao dịch. Lớp TransactionScope vừa được tạo ra để làm việc với ADO.NET persistence cleaner.

Edit: Làm rõ tuyên bố của tôi liên quan đến casperOne's addition nó là TransactionScope rằng sẽ tạo ra các giao dịch và kết nối sau đó sẽ thấy những giao dịch đó được tạo ra bởi các TransactionScope và sử dụng nó vì nó có sẵn cho nó.

+0

@Christ Marisic: Đó là cách khác. Kết nối tìm kiếm sự hiện diện của một Giao dịch cho chuỗi hiện tại, được tạo bởi TransactionScope. Nếu có, thì nó sẽ mở rộng với Giao dịch. Sau đó, điều phối viên sẽ yêu cầu kết nối cam kết hoặc quay lại. – casperOne

69

Cần lưu ý rằng khi sử dụng TransactionScope, bạn không cần phải có cấu trúc try/catch. Bạn chỉ cần gọi Complete trên phạm vi để thực hiện giao dịch khi phạm vi được thoát.

Điều đó đang được nói, TransactionScope thường là lựa chọn tốt hơn vì nó cho phép bạn lồng các cuộc gọi đến các phương thức khác có thể yêu cầu giao dịch mà không cần phải chuyển trạng thái giao dịch.

Khi gọi BeginTransaction trên đối tượng DbConnection, bạn phải chuyển đối tượng giao dịch đó xung quanh nếu bạn muốn thực hiện các thao tác khác trong cùng một giao dịch, nhưng theo một phương pháp khác.

Với TransactionScope, miễn là phạm vi tồn tại, nó sẽ xử lý mọi thứ đăng ký với Transaction hiện tại trên luồng, làm cho mã của bạn sạch hơn và dễ bảo trì hơn.

Trên hết, bạn có thêm lợi ích khi có thể sử dụng các tài nguyên khác có thể tham gia vào giao dịch, không chỉ kết nối với cơ sở dữ liệu.

Cần lưu ý rằng trong trường hợp bạn cần phải tận dụng tối đa các kết nối và hoạt động cơ sở dữ liệu, bạn có thể không muốn sử dụng TransactionScope; thậm chí đối với một cơ sở dữ liệu duy nhất, bạn chạy khả năng của Điều phối viên giao dịch phân tán đang được sử dụng và có giao dịch được chuyển thành một giao dịch phân tán (ngay cả đối với một kết nối cơ sở dữ liệu).

Trong những trường hợp này, trong khi làm lộn xộn thiết kế của bạn, bạn có thể cân nhắc việc chuyển giao một giao dịch cụ thể cho từng kết nối.

Hoặc, nếu bạn biết bạn sẽ sử dụng một tài nguyên nhất quán (và trên cùng một chuỗi), bạn có thể muốn tạo lớp tham chiếu đếm kết nối/giao dịch của mình.

Bạn sẽ tạo một lớp học đang được xây dựng, tạo tài nguyên/số gia số của bạn. Nó cũng sẽ thực hiện IDisposable (trong đó bạn sẽ giảm/phát hành/cam kết/hủy bỏ khi đếm là số không), và lưu trữ số đếm trong một biến có áp dụng ThreadStaticAttribute.

Điều này cho phép bạn tách quản lý giao dịch khỏi mã logic và vẫn giữ một nguồn tài nguyên số ít hiệu quả (thay vì chuyển sang giao dịch phân phối).

+0

nếu tôi sử dụng kết nối duy nhất với giao dịch thì không phải là nó giống nhau không? Ý tôi là bạn tránh giao dịch phân phối .. – GorillaApe

+0

@Parhs Phụ thuộc vào việc bạn có tài nguyên giao dịch khác được nhập ngũ trong giao dịch với kết nối cơ sở dữ liệu đơn lẻ hay không. – casperOne

+0

nhà cung cấp dịch vụ của tôi không cho phép các giao dịch lồng nhau (cơ sở dữ liệu), vậy vẫn còn một vấn đề? – GorillaApe

19

Một khác biệt lớn (bài học kinh nghiệm theo cách khó) - TransactionScope sử dụng MS DTC để quản lý giao dịch.

Nếu ứng dụng của bạn chỉ quản lý giao dịch cơ sở dữ liệu và không có dịch vụ hoặc cuộc gọi từ xa, bạn có thể bỏ qua các vấn đề liên quan đến MS DTC bằng cách sử dụng giao dịch gốc với cơ sở dữ liệu (DbTransactions).

+0

tôi cũng đã học được điều này một cách khó khăn! Nhưng vui mừng vì đã giải quyết cơn ác mộng với msdtc – DevDave

+0

Mayank (hoặc bất kỳ ai khác). Tôi gặp phải các vấn đề khác với Transaction và UnitTesting, bạn có thể giúp tôi với http://stackoverflow.com/questions/9636533/mvc3-differences-between-test-environment-and-dev-application này không? – DevDave

+5

Điều này không đúng trong mọi lúc.'TransactionScope' sẽ chuyển từ giao dịch hạt nhân lên đến giao dịch DTC tùy theo nhu cầu. Tuy nhiên, đây là tất cả ẩn từ bạn. Điểm quan trọng là nó không * luôn luôn * làm điều này, nhưng * khi cần thiết *. – casperOne

4

TransactionScope cung cấp quản lý thống nhất cho tất cả người quản lý tài nguyên (máy chủ SQL, thư mục hoạt động, hệ thống tệp,…). Hơn nữa, người ta có thể viết trình quản lý tài nguyên riêng: mã phát hiện phạm vi giao dịch, tham gia và hoạt động chính xác như máy chủ SQL: cam kết hoặc hoàn nguyên các thay đổi như những người tham gia giao dịch khác. Tôi tin rằng TransactionScope là chính và quên MS SQL giao dịch bản địa cho đến khi thất bại vào bẫy lớn: Windows Server 2008 WEB Edition đi kèm với dịch vụ điều phối giao dịch phân phối hạn chế và phạm vi giao dịch hoạt động trên máy tính duy nhất. Ứng dụng ASP.NET của bạn sẽ không thành công trên hệ thống này nếu máy chủ IIS và SQL được cài đặt trên các máy tính khác nhau. Hãy xem xét rằng hầu hết các nhà cung cấp miền công cộng cung cấp phiên bản Windows Server WEB và máy chủ SQL đều nằm trên các máy chủ riêng biệt. Điều này có nghĩa là bạn phải làm việc với các giao dịch tự nhiên bằng cách sử dụng quản lý giao dịch rõ ràng…