java - Spring mongo 线程安全

标签 java spring-boot concurrency

我正在学习 Spring Boot 和并发。我知道当spring boot收到多个请求时,它会启动多个线程来处理请求。我这里有一个访问 mongo 的方法。此方法将保存一个新的 someResult(可能包含调用者设置的一些新值)。我的问题是,如果我的 spring boot Controller 有 100 个并发调用,并且我得到 someResult 对象,并设置值和保存等,这些值会不一致吗?

  public void upsert(SomeResult someResult) {
        String collection = this.SomeResultConfig.getCollectionSomeResultCollection();
        String queryStr = "{testingID : '%s'}";
        queryStr = String.format(queryStr, someResult.getTestingID());
        Query query = new BasicQuery(queryStr);
        List<SomeResult> someResultList = this.mongoOps.find(query, SomeResult.class, collection);
        if (someResult.size() != 0) {
            this.mongoOps.findAllAndRemove(query, collection);
        }
        this.mongoOps.save(someResult, collection);
    }

最佳答案

是的,有可能 2 个线程先读取结果,然后进行修改,然后每个线程将修改写入数据库。数据库状态以其中一个值结束 - 后一个,较早的写入丢失 - 这称为丢失更新现象。
除了使用具有足够隔离级别的事务之外,您还可以使用乐观锁定。

The @Version annotation provides syntax similar to that of JPA in the context of MongoDB and makes sure updates are only applied to documents with a matching version. Therefore, the actual value of the version property is added to the update query in such a way that the update does not have any effect if another operation altered the document in the meantime. In that case, an OptimisticLockingFailureException is thrown. The following example shows these features:


https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo-template.optimistic-locking
在您的代码中,您可以决定是否要在抛出异常时重试整个操作,或者是否向用户报告错误。

关于java - Spring mongo 线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62432698/

相关文章:

java - 如何根据属性找出两个数组列表之间的差异?

java - 可以使用共享的 Random 实例来获得高斯分布吗

java - 如何声明 Java 数组并向其中插入数据

c++ - 用于 Sutter 的无锁队列的 Boost 库或 C++0x 原子的等效实现?

Kotlin 协程比线程花费更长的时间

Django + Postgresql -> 未处理的异常

java - Struts2中,使用成员值动态生成表单元素名称

java - 使用 ./gradlew appRun 运行 Spring Boot 应用程序

java - 微服务和maven结构

java - 通过 maven for Spring Boot 应用程序为 AWS Beanstalk 创建 .ebextensions 的正确方法是什么