2013-11-23 29 views
5

Im phải đối mặt với một vấn đề mà có lẽ là khá phổ biến nhưng tôi không thể tìm thấy bất kỳ giải pháp cho nó. Sự cố xảy ra khi người dùng có các thực thể trong bộ nhớ cache trên máy khách và một người dùng khác loại bỏ một số thực thể đó (trên máy chủ). Khi người dùng đầu tiên muốn cập nhật dữ liệu của mình, các thực thể đã loại bỏ sẽ không bị xóa khỏi bộ nhớ cache. Bạn có thể giải quyết nó bằng cách xóa bộ nhớ cache mỗi khi bạn cập nhật nhưng sau đó bạn cũng mất tất cả các thay đổi không được lưu. Tôi có thiếu điều gì đó hiển nhiên không?Làn gió: Xóa các thực thể khỏi bộ nhớ cache bị người dùng khác xóa khỏi cơ sở dữ liệu mà không xóa toàn bộ bộ nhớ cache?

Ví dụ:

mẫu:

public class Order 
{ 
    [Key] 
    public int Id { get; set; } 
    public ICollection<OrderDetail> OrderDetails { get; set; } 
} 

public class OrderDetail 
{ 
    [Key] 
    public int Id { get; set; } 
    [ForeignKey("Order")] 
    public int Order_Id { get; set; } 
    public virtual Order Order { get; set; } 
} 

Khách hàng mã:

function getOrder(orderId, orderObservable) { 
    var query = EntityQuery.from("Orders") 
       .where("orderId", "==", orderId) 
       .expand("orderDetails"); 
    return manager.executeQuery(query).then(querySucceeded).fail(queryFailed); 

    function querySucceeded(data) {    
     var order = data.results[0]; 
     // NOTE: the removed orderdetail is still there 'order.orderDetails' 
     orderObservable(order); 
    } 
} 

Step-by-step kịch bản:

  1. dùng A truy vấn cho một đơn đặt hàng với mình lệnh chi tiết tương ứng.
  2. Đơn đặt hàng và đơn đặt hàng sau đó được đặt trong bộ nhớ cache.
  3. Người dùng B loại bỏ một đơn đặt hàng và lưu các thay đổi cho máy chủ.
  4. Người dùng Truy vấn để nhận các bản cập nhật mới nhất cho đơn hàng.
  5. Khi truy vấn trả về đơn hàng đã bị xóa vẫn còn đó.

Trong các tài liệu dễ dàng, dưới tiêu đề "Lưu ý quan trọng về xóa bộ nhớ cache", có giải pháp xóa các thực thể được lưu trong bộ nhớ cache bằng cách so sánh bộ nhớ cache và kết quả từ truy vấn và tách các thực thể bị thiếu trong kết quả. http://www.breezejs.com/documentation/entitymanager-and-caching Nhưng điều đó không hoạt động trong trường hợp này. Tôi đoán nó đã làm với thực tế là orderdetails có liên quan đến thứ tự và rằng nó được "nhặt" từ bộ nhớ cache trước khi nó được thông qua để gọi lại thành công.

Tất cả trợ giúp đều được đánh giá cao!

+0

Hãy thử cách này: http: //blogs.msdn.com/b/diego/archive/2012/04/01/tips-to-avoid-deadlocks-in-entity-framework-applications.aspx. –

Trả lời

3

Sự cố bạn đang gặp phải không phải với Breeze, nhưng với thiết kế nói chung. Có một số tùy chọn mà bạn cần lưu ý -

  1. Sử dụng SignalR để thông báo cho bất kỳ thực thể nào đã bị xóa khỏi bộ nhớ cache.

  2. Sử dụng cờ được lưu trữ hoặc đã xóa thay vì xóa các thực thể khỏi cơ sở dữ liệu.

Cả hai đều có ưu điểm và nhược điểm của chúng.

Với SignalR bạn sẽ cần phải nhận được công việc đường ống tại chỗ cho các thông báo và thiết lập một quy trình làm việc cụ thể xung quanh việc loại bỏ các đối tượng bị xóa

manager.detachEntity(entityToDetach); 

Lý do bạn sẽ tách thay vì xóa là bởi vì nếu bạn đặt nó để xóa thì trình quản lý thực thể Breeze của bạn vẫn nghĩ rằng bạn cần phải duy trì sự thay đổi đó đối với cơ sở dữ liệu.

Nếu bạn sử dụng một lá cờ sau đó bạn chỉ có thể thiết lập logic kinh doanh của bạn để bỏ qua thực thể được gắn cờ là xóa hoặc lưu trữ và khi bạn truy vấn DB nó sẽ trở lại sự thay đổi cho đơn vị đó và ngừng hiển thị nó

myEntity().archived(true); 

Vấn đề ở đây sẽ là nếu thực thể của bạn không khớp với truy vấn của bạn, nó sẽ không bao giờ trả về thực thể được cập nhật để cho khách hàng biết rằng nó đã được lưu trữ hoặc bị xóa. Các báo trước khác là bạn sẽ có thông tin nằm xung quanh trong cơ sở dữ liệu của bạn mà không hoạt động nữa.

Tùy thuộc vào loại ứng dụng và yêu cầu bạn có, bạn nên thực hiện một trong các lựa chọn này hoặc tìm ra một lựa chọn khác. Hy vọng rằng sẽ giúp.

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