[英]Spring with JPA: Queue concurrent access to JPA entity from different requests
我有一個Spring Web Application,可以同時訪問某些資源。 該資源保存了可能由請求獲取的一定數量的對象的列表。 如果列表為空,則不再返回SomeClass對象
該資源如下所示:
public class Resource {
private List<SomeClass> someList;
public List<SomeClass> fetch() {
List<SomeClass> fetched = new ArrayList<SomeClass>();
int max = someList.size();
if(max<=0) {
return fetched;
}
int added = 0;
while(added<max) {
int randomIndex = Math.random(max-1);
SomeClass someClass = someList.get(randomIndex);
if(!fetched.contains(someClass)) {
fetched.add(someClass);
++added;
}
}
someList.remove(fetched);
return fetched;
}
}
此資源被加載到服務層中,然后被訪問並保存回數據庫中:
@Service
public class ResourceService {
@Autowired
private ResourceRepository repo;
public List<SomeClass> fetch(long id) {
Resource resource = repo.findOne(id);
List<SomeClass> fetched = resource.fetch();
repo.save(resource);
return fetched;
}
}
我嘗試在ResourceService#fetch方法上使用@Transactional來避免兩個並發請求可能會從列表中獲取SomeClass對象的問題,盡管該列表已被第一個請求清空,但是我不確定這是否是正確的方法...我必須在Resource#fetch方法上使用@Synchronized還是在服務層中引入顯式的Lock?
我需要確保只有一個請求可以訪問資源(獲取SomeClass對象的列表)而不會引發異常。 取而代之的是,應將后續請求排隊,並在當前請求完成獲取SomeClass對象列表之后嘗試訪問資源。
我的最終解決方案是在@Service中引入一個阻塞隊列 ,並將所有傳入請求添加到該隊列中。 然后,一個單獨的線程從隊列中取出一個元素並對其進行處理。
我認為這是最干凈的解決方案,因為添加ReentrantLock會阻止請求處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.