Đá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#