Spring 使用 JPA:排队从不同请求到 JPA 实体的并发访问

Spring with JPA: Queue concurrent access to JPA entity from different requests

我有一个 Spring Web 应用程序可以并发访问特定资源。该资源包含一定数量的对象列表,这些对象可能会被请求获取。如果列表为空,则不应再返回任何 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 对象列表后尝试访问资源。

我的最终解决方案是在添加元素后立即从队列中引入一个 Blocking Queue in the @Service and add all incoming requests to it. A seperate thread is then taking 元素并对其进行处理。

我认为这是最干净的解决方案,因为添加 ReentrantLock 会阻止请求处理。