2010-06-24 33 views
7

Chúng tôi có một ứng dụng Java sử dụng MySQL, Hibernate (3.5.1-Final) và EHcache (1.2.3) cho bộ nhớ cache cấp 2 của chúng tôi.Bộ nhớ cache cấp 2 Hibernate ObjectNotFoundException với số lượng lớn các giao dịch đồng thời

chúng tôi mức hibernate.properties cô lập là Read-cam ly = 2

# 2-Read committed isolation 
hibernate.connection.isolation=2 

Theo một số lượng lớn các giao dịch đồng thời, chúng ta đang thấy một vấn đề mà các bộ sưu tập nhất định (các hiệp hội DB) khi nạp sẽ ném một ObjectNotFoundException và có vẻ như bộ nhớ cache cấp 2 đang trả về một bản sao cũ của bộ sưu tập đó.

Chúng tôi có nhiều loại giao dịch khác nhau truy cập bộ sưu tập này (chỉ đọc) và chỉ một cặp có thể thêm/xóa các mục khỏi bộ sưu tập này.

Chúng tôi không thấy vấn đề này dưới tải giao dịch đơn lẻ hoặc thậm chí tải giao dịch vừa phải (10 - 20 kết nối đồng thời).

Ví dụ chúng ta có một thực thể nhân vật:

@Entity 
@Table(name = "CHARACTERS") 
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
public class Character extends AbstractCharacter implements Serializable { 
... 
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
    @OneToMany(mappedBy = "character", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    private Set<CharacterItem> items; 

Chúng tôi đang duy trì đúng đồ thị đối tượng khi xóa các đối tượng bằng cách loại bỏ chúng khỏi bộ sưu tập mà họ đang chứa trong và gọi session.delete().

character.getItems().remove(characterItem); 
    session.delete(characterItem); 

Chúng tôi đã thử thay đổi mục Đặt; CacheConcurrencyStrategy từ:

@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
private Set<CharacterItem> items; 

Để

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
private Set<CharacterItem> items; 

Với không may mắn.

Chúng tôi không sử dụng khóa cơ sở dữ liệu thay vì chúng tôi sử dụng optimistic concurrency control để bắt và thử lại các giao dịch xung đột.

Các chỉ có 2 giải pháp chúng ta có thể thấy vào thời điểm này là:

  1. Cố gắng nắm bắt những ObjectNotFoundException và cố gắng một cách thông minh đuổi bộ sưu tập (mặc dù có dường như không đủ bối cảnh ngoại trừ)

  2. Sử dụng @NotFound(action=NotFoundAction.IGNORE) chú thích về bộ sưu tập các mặt hàng, mà sẽ bỏ qua và không ném ObjectNotFoundException (nhưng chúng tôi có mối quan tâm như thế nào này hoạt động với mức độ ca 2 che và đảm bảo rằng nó đang xem dữ liệu thích hợp).

Tôi muốn có một @NotFound (action = NotFoundAction.EVICT_2ND_LEVEL_CACHE_RELOAD), nơi nó sẽ đuổi đối tượng từ bộ nhớ cache và cố gắng tải lại bộ sưu tập. Chúng tôi cũng có thể thử thay đổi FetchyType từ LAZY thành EAGER nhưng tôi muốn cố gắng tìm hiểu vấn đề và chọn giải pháp tốt nhất sẽ cung cấp dữ liệu đó trong các giao dịch của chúng tôi nhất quán theo đồng thời cao.

+0

Bạn đã bao giờ giải quyết vấn đề này chưa? Tôi có cùng một vấn đề. – cherouvim

Trả lời

1

Có thể bạn nên thử session.evict(characterItem) thay vì session.delete?

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