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 会阻止请求处理。
我有一个 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 会阻止请求处理。