Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
防止javaweb服务并发修改记录_Java_Multithreading_Spring_Tomcat - Fatal编程技术网

防止javaweb服务并发修改记录

防止javaweb服务并发修改记录,java,multithreading,spring,tomcat,Java,Multithreading,Spring,Tomcat,我正在Tomcat内部运行一个Java web服务 该服务被多个Rails应用程序使用,这些应用程序本应协调并发修改,但做得不是很好 感兴趣的服务方法只有一种,它尝试放置用户记录,但它需要大量处理,并且可能需要一段时间。当前一个调用仍在处理中时,这些Rails应用程序中很可能会有多个尝试将更改推送到同一用户 我对Tomcat每个请求一个线程的理解是,我实际上是在处理一个多线程问题,但我不想在服务对象上同步,而是想在临时用户id上进行同步 我考虑使用一个集合来存储当前处理的用户ID,然后在集合的对

我正在Tomcat内部运行一个Java web服务

该服务被多个Rails应用程序使用,这些应用程序本应协调并发修改,但做得不是很好

感兴趣的服务方法只有一种,它尝试放置用户记录,但它需要大量处理,并且可能需要一段时间。当前一个调用仍在处理中时,这些Rails应用程序中很可能会有多个尝试将更改推送到同一用户

我对Tomcat每个请求一个线程的理解是,我实际上是在处理一个多线程问题,但我不想在服务对象上同步,而是想在临时用户id上进行同步

我考虑使用一个集合来存储当前处理的用户ID,然后在集合的对象上进行同步。第一个能够将用户id添加到集合中的用户将进入进程,而发现集合中已经存在的用户id的用户将返回409冲突错误

Set<String> activeUserIds = new HashSet<String>();

// annotations, mappings, etc.
public ResponseEntity<String> putUser(User user) {

    boolean canProcess;
    synchoronize(activeUserIds) {
        canProcess = activeUserIds.add(user.getId()) {
    }

    if (!canProcess) {
        return new ResponseEntity<String>("user already being modified", Status.CONFLICT);
    }

    // perform service activity

    synchoronize(activeUserIds) {
        activeUserIds.remove(user.getId()) {
    }

}
Set activeUserIds=new HashSet();
//注释、映射等。
公共响应用户(用户){
布尔过程;
同步(ActiveUserID){
canProcess=activeuserid.add(user.getId()){
}
if(!canProcess){
返回新的ResponseEntity(“用户已被修改”,状态为.CONFLICT);
}
//执行服务活动
同步(ActiveUserID){
ActiveUserId.remove(user.getId()){
}
}

这听起来可行吗?我还没有发现任何内置于Tomcat或Spring MVC中的东西能够自动处理这种行为,但是否已经有一个我不知道的内置解决方案?

我认为您提出的解决方案应该可行,只要您有一个webapp运行实例(正如欧文在评论中指出的那样)。我不知道有任何内置解决方案能够做到这一点

为了使代码更易于阅读,您还可以使用一个synchronized set并去掉两个
synchronized
语句:

Set<String> activeUserIds = Collections.synchronizedSet(new HashSet<String>());
Set activeUserIds=Collections.synchronizedSet(newhashset());

任何使用Java并发操作(仅限)的解决方案都只能在应用程序未跨多台计算机/JVM群集的情况下工作。用户记录使用什么后端存储?如果使用SQL数据库,则可以在请求处理代码的开头锁定行。