2010-09-16 31 views
5

Đánh giá .NET Entity Framework Tôi cố gắng tìm các mẫu phù hợp để xử lý các cập nhật đồng thời với chế độ đồng thời lạc quan.Xử lý khung thực thể OptimisticConcurrencyException

Trong documentation và nhiều nơi khác tôi thấy mô hình sau:

 

Try 
    ' Try to save changes, which may cause a conflict. 
    Dim num As Integer = context.SaveChanges() 
    Console.WriteLine("No conflicts. " & num.ToString() & " updates saved.") 
Catch generatedExceptionName As OptimisticConcurrencyException 
    ' Resolve the concurrency conflict by refreshing the 
    ' object context before re-saving changes. 
    context.Refresh(RefreshMode.ClientWins, orders) 

    ' Save changes. 
    context.SaveChanges() 
    Console.WriteLine("OptimisticConcurrencyException handled and changes saved") 
End Try 

tôi nhìn thấy những vấn đề sau đây với điều này

  • nó tự động thực hiện cuối cùng trong chiến thắng thay vì sử dụng lạc chế độ
  • không mạnh mẽ: các thay đổi đồng thời giữa .Refresh và .SaveChanges có thể gây ra một OptimisticConcurrencyException mới

Điều này có đúng không, hoặc tôi có thiếu gì đó không?

Trong một UI Tôi thường cho phép người dùng giải quyết xung đột đồng thời:

 

Try 
    _ctx.SaveChanges() 
Catch ex As OptimisticConcurrencyException 
    MessageBox.Show("Data was modified by another User." & vbCrLf & 
    "Click 'Refresh' to show the current values and reapply your changes.", 
    "Concurrency Violation", MessageBoxButton.OK) 
End Try 

Trong logic kinh doanh Tôi thường sử dụng một vòng lặp retry xung quanh giao dịch kinh doanh toàn (đọc và cập nhật):

 

Const maxRetries = 5, retryDelayMs = 500 
For i = 1 To maxRetries 
    Try 
     Using ctx As New EFConcurrencyTest.ConcurrencyTestEntities 
      ctx.Inventories.First.QuantityInStock += 1 
      System.Threading.Thread.Sleep(3000) 'Cause conflict 
      ctx.SaveChanges() 
     End Using 
     Exit For 
    Catch ex As OptimisticConcurrencyException 
     If i = maxRetries Then Throw 
     System.Threading.Thread.Sleep(retryDelayMs) 
    End Try 
Next 

W thứ i EF tôi có kế hoạch để đóng gói các vòng lặp:

 

ExecuteOptimisticSubmitChanges(Of EFConcurrencyTest.ConcurrencyTestEntities)(
    Sub(ctx) 
     ctx.Inventories.First.QuantityInStock += 1 
     System.Threading.Thread.Sleep(3000) 'Cause conflict 
    End Sub) 

Xem:

Functional Optimistic Concurrency in C#

Retryable actions in C#

Trả lời

6

này:

Catch ex As OptimisticConcurrencyException 
    ' Resolve the concurrency conflict by refreshing the 
    ' object context before re-saving changes. 
    context.Refresh(RefreshMode.ClientWins, orders) 

    ' Save changes. 
    context.SaveChanges() 
    Console.WriteLine("OptimisticConcurrencyException handled and changes saved") 

... hoàn toàn vô nghĩa. Nếu điều duy nhất bạn làm khi bạn "xử lý" ngoại lệ là bỏ qua nó và lưu anyway, bạn chỉ cần bật đồng thời lạc quan tắt; bạn đang viết mã để làm việc xung quanh một tính năng tùy chọn.

Vì vậy, vâng, tôi muốn nói tài liệu không cung cấp cho bạn lời khuyên tốt ở đây.

Mã giao diện người dùng được đề xuất của bạn là giải pháp tốt hơn.

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