簡體   English   中英

Spring with JPA:將來自不同請求的對JPA實體的並發訪問排隊

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM