2009-05-15 13 views

Trả lời

13

Tôi sử dụng chúng trong việc kiểm tra tất cả các thời gian :)

try 
{ 
    dc.Connection.Open(); 
    dc.Transaction = dc.Connection.BeginTransaction(); 

    dc.SubmitChanges(); 
} 
finally 
{ 
    dc.Transaction.Rollback(); 
} 

CẬP NHẬT

này sẽ LUÔN rollback sau khi thực tế. Tôi sử dụng nó trong thử nghiệm.

+3

Bạn nên đề cập đến rằng _always_ mẫu của bạn trở lại trạng công việc của mình, hay tôi sai và dc.Transaction.Rollback() không có hại sau dc.SubmitChanges ()? – VVS

+0

-1: Nên có khối sử dụng cho giao dịch thay vì thử/cuối cùng để đảm bảo dọn dẹp. – Richard

+4

@Richard: Tôi đang đợi bạn một đoạn trích bằng cách sử dụng khối 'đang sử dụng' giống ngữ pháp của tôi. – leppie

9

Something như thế này, có lẽ:

try 
{ 
    using (TransactionScope scope = new TransactionScope()) 
    { 
     //Do some stuff 

     //Submit changes, use ConflictMode to specify what to do 
     context.SubmitChanges(ConflictMode.ContinueOnConflict); 

     scope.Complete(); 
    } 
} 
catch (ChangeConflictException cce) 
{ 
     //Exception, as the scope was not completed it will rollback 
} 
+0

Tại sao bỏ phiếu xuống? Một lời giải thích nhỏ sẽ không làm tổn thương ... – Philippe

+1

Đây là câu trả lời hay nhất cho đến nay, IMO. Phạm vi giao dịch là con đường để đi. Điều này cũng chỉ định một ConflictMode và ít nhất là gợi ý một số hình thức xử lý lỗi thích hợp. Công việc tốt. – Triynko

+0

Điều này làm việc cho tôi, cảm ơn @philippe. –

14

Một DataContext sẽ đón một giao dịch môi trường xung quanh theo mặc định, vì vậy nó chỉ là vấn đề đảm bảo có một giao dịch trong phạm vi. Các chi tiết trở thành vấn đề chính:

  • Những tùy chọn nào bạn cần (ví dụ như mức độ cách ly)
  • Bạn có muốn một giao dịch mới hoặc tái sử dụng một giao dịch hiện có (ví dụ như một hoạt động kiểm toán/khai thác gỗ có thể yêu cầu một giao dịch mới để nó có thể được cam kết ngay cả khi hoạt động kinh doanh tổng thể thất bại và do đó giao dịch bên ngoài được khôi phục).

Điều này được đơn giản hóa một số mã mẫu, mã thực sự sử dụng người trợ giúp để tạo giao dịch với các tùy chọn chính sách (một trong các mục đích của nguyên mẫu là để kiểm tra tác động của các tùy chọn này).

using (var trans = new TransactionScope(
          TransactionScopeOption.Required, 
          new TransactionOptions { 
           IsolationLevel = IsolationLevel.ReadCommitted 
          }, 
          EnterpriseServicesInteropOption.Automatic)) { 
    // Perform operations using your DC, including submitting changes 

    if (allOK) { 
     trans.Complete(); 
    } 
} 

Nếu Complete() không được gọi thì giao dịch sẽ được khôi phục. Nếu có một phạm vi giao dịch có chứa thì cả giao dịch bên trong và bên ngoài cần phải hoàn thành cho các thay đổi trên cơ sở dữ liệu được cam kết.

+2

+1 để bao gồm thay đổi IsolationLevel cho SQL Server. Giải thích tại đây: http://blogs.msdn.com/b/dbrowne/archive/2010/05/21/using-new-transactionscope-considered-harmful.aspx Tại sao EnterpriseServicesInteropOption.Automatic? –

+0

allOK đến từ đâu? Intelli-type của tôi không phải là chọn nó lên. – Kukoy

+0

@Fritos: Mã chạy trong giao dịch (ví dụ: thay thế cho nhận xét). – Richard

9

Nó không đơn giản như phương thức TransactionScope nhưng, như tôi đã hiểu, đây là cách "đúng" để làm điều đó cho LINQ-to-SQL. Nó không yêu cầu bất kỳ tham chiếu đến System.Transactions.

dataContext.Connection.Open(); 
using (dataContext.Transaction = dataContext.Connection.BeginTransaction()) 
{ 
    dataContext.SubmitChanges(); 

    if (allOK) 
    { 
     dataContext.Transaction.Commit(); 
    } 
    else 
    { 
     dataContext.Transaction.RollBack(); 
    } 
} 

Tất nhiên, chỉ cần RollBack nếu bạn định thực hiện thêm thao tác dữ liệu trong khi sử dụng, nếu không thay đổi sẽ tự động bị hủy.

+0

allOK đến từ đâu? Intelli-type của tôi không phải là chọn nó lên. – Kukoy

+4

@Fritos: Đó là mã giả – abatishchev

+1

Điều này có vẻ đơn giản hơn câu trả lời được chấp nhận. Bất kỳ ý tưởng tại sao nó không phải là câu trả lời được chấp nhận? – ChrisFox

0

là một cái gì đó như thế này:

using (YourDatacontext m_DB = new YourDatacontext()) 
using (TransactionScope tran = new TransactionScope()) 
{ 
    try 
    { 
     //make here the changes 
     m_DB.SubmitChanges(); 
     tran.Complete(); 
    } 
    catch (Exception ex) 
    { 
     Transaction.Current.Rollback(); 
    } 
} 
Các vấn đề liên quan