Java Spring with JPA:对来自不同请求的JPA实体的并发访问进行排队
我有一个SpringWeb应用程序,可以并发访问特定的资源。此资源包含一个特定数量的对象列表,这些对象可能由请求获取。如果列表为空,则不应再返回任何SomeClass对象 资源如下所示:Java Spring with JPA:对来自不同请求的JPA实体的并发访问进行排队,java,spring-mvc,jpa,concurrency,spring-data-jpa,Java,Spring Mvc,Jpa,Concurrency,Spring Data Jpa,我有一个SpringWeb应用程序,可以并发访问特定的资源。此资源包含一个特定数量的对象列表,这些对象可能由请求获取。如果列表为空,则不应再返回任何SomeClass对象 资源如下所示: public class Resource { private List<SomeClass> someList; public List<SomeClass> fetch() { List<SomeClass> fetched = new
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;
}
}
我尝试在ResourceServicefetch方法上使用@Transactional来避免两个并发请求可能从列表中获取SomeClass对象的问题,尽管第一个请求已经清空了列表,但我不确定这是否是正确的方法。。。我必须在Resourcefetch方法上使用@Synchronized,还是在服务层中引入显式锁
我需要确保只有一个请求正在访问获取SomeClass对象列表的资源,而不会引发异常。相反,后续请求应该排队,并在当前请求完成获取SomeClass对象列表后尝试访问资源。我的最终解决方案是在@Service中引入一个,并将所有传入请求添加到该服务中。一个单独的线程是队列中的一个元素,只要添加一个线程并对其进行处理
我认为这是最干净的解决方案,因为添加一个将阻止请求处理 我认为简单地同步Java synchronize会有所帮助,因为默认情况下,所有SpringBean都是单例的,JVM中只有一个Bean实例。我还需要ResourceServicefetch mehotd上的@Transactional吗?如果两个请求从数据库加载资源,第一个请求获取其列表,然后第二个请求尝试获取其列表,尽管数据库中的资源尚未更新,因此两个请求都使用相同的对象!?对不起,我没有仔细阅读您的问题:资源是JPA实体吗?在这种情况下,您可以使用。我是否正确理解ResourceService==浏览器的客户端?是的,资源是一个JPA实体。。问题是,我不能使用乐观锁定,因为据我所知,这会引发异常,但我需要客户端排队以访问资源,因此第二个请求在第一个请求完成后访问资源。。是的,我的resourceservice的客户端可能是一个浏览器应用程序,或者一些原生android应用程序。我不认为这真的很重要。当浏览器请求一个资源并且从不更新它时,会发生什么,也就是说从不释放锁?你有关于如何做的更多信息吗,任何链接?或者github项目有什么例子吗?