java - 防止 Java Web 服务并发修改记录

标签 java multithreading spring tomcat

我在 Tomcat 中运行 Java 网络服务。

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

只有一种服务方法值得关注,它会尝试 PUT 用户记录,但它会进行大量处理并且可能需要一段时间。很可能不止一个这样的 Rails 应用程序会尝试在先前的调用仍在处理时将更改推送给同一用户。

我对 Tomcat 的一个线程一个请求的理解是,我实际上是在处理一个多线程问题,但我不想在服务对象上同步,而是想以某种方式在 transient 用户 ID 上同步。

我想到了使用 Set 来存储当前处理的用户 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()) {
    }

}

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

最佳答案

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

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

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

关于java - 防止 Java Web 服务并发修改记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25696230/

相关文章:

java - 使用.sh文件执行java程序时出错

java - 如何使用 Intent 将具有不可序列化子对象的可序列化对象从一个 Android Activity 发送到另一个 Activity

java - 空白弹出菜单和组合框

java - stackoverflow 如何影响 mule 中的池化组件?

spring - 有效解决 501 HTTPS Required Error in Maven Build for Moving (http ://repo1. maven.org/maven2 & http ://repo. spring.io) to HTTPS?

java - 使用 MOM 的 Java Spring 微服务示例

java - 创建一个新线程将对象保存到文件

java - Servlet未获取请求参数

Java,如何制作一个监视程序状态的线程?

spring - Spring-boot中将redis-cache反序列化为对象的问题