Trong ứng dụng web của tôi, tôi có một số chủ đề có khả năng truy cập cùng một dữ liệu đồng thời tại sao tôi quyết định thực hiện lạc quan (phiên bản) và khóa bi quan với Hibernate.Làm thế nào để khóa và tải lại một thực thể đúng
Hiện nay tôi sử dụng mẫu sau để khóa một thực thể và thực hiện các hoạt động ghi trên đó (sử dụng quản lý Springs giao dịch và ranh giới giao dịch với @Transactional):
@Transactional
public void doSomething(entity) {
session.lock(entity, LockMode.UPGRADE);
session.refresh(entity);
// I change the entity itself as well as entites in a relationship.
entity.setBar(...);
for(Child childEntity : entity.getChildren()) {
childEntity.setFoo(...);
}
}
Tuy nhiên, đôi khi tôi nhận được StaleObjectException
khi @ Giao dịch là đỏ bừng mà nói với tôi rằng một ChildEntity đã được sửa đổi đồng thời và bây giờ có một phiên bản sai.
Tôi đoán tôi là không làm mới chính xác entity
và con của nó vì vậy tôi đang làm việc với dữ liệu cũ. Ai đó có thể chỉ ra cách để đạt được điều này? Một số suy nghĩ của tôi bao gồm xóa bối cảnh kiên trì (phiên) hoặc gọi lại số session.lock(entity, LockMode.READ)
, nhưng tôi không chắc điều gì đúng ở đây.
Cảm ơn sự giúp đỡ của bạn!
Tôi đang sử dụng MySQL InnoDB hỗ trợ "CHỌN ... CHO CẬP NHẬT", vì vậy tôi không thấy vấn đề ở đây. Hơn nữa, tôi cũng đang khóa lạc quan, để có được một "thông báo" khi một sửa đổi đồng thời được thực hiện. – Erik
Xin lỗi, đã bỏ lỡ điểm bạn gặp vấn đề với trẻ em (được in đậm :)). Tôi đã cập nhật câu trả lời ... – Stas
Trong mã của tôi, tôi luôn luôn khóa trên thực thể, ngay cả khi tôi chỉ muốn cập nhật các thực thể không phải là trẻ em. Vì vậy, cũng nên có khóa mua lại. Quan tâm chính của tôi là tôi không làm việc với thực thể/trẻ em mới nhất bằng cách chỉ sử dụng làm mới. – Erik