如何在 Spring Data MongoDB 中使用乐观锁定?

Posted

技术标签:

【中文标题】如何在 Spring Data MongoDB 中使用乐观锁定?【英文标题】:How to use optimistic locking with Spring Data MongoDB? 【发布时间】:2015-11-12 03:21:24 【问题描述】:

我正在浏览Spring Data MongoDB - Reference Documentation,我发现这些示例有点过于简单了。

特别是我试图了解如何在并发环境中处理陈旧数据。例如,假设我有以下实体:

public class Person 

    private final String username;
    private final String firstname;
    private final String lastname;

    [...]


现在,如果我使用CrudRepository 来保存/更新/删除我的实体,那么想象一个场景,其中两个线程检索同一个实体,其中一个删除它,另一个更新它的lastname 字段。如果delete 调用在save 调用之前完成,那么我的实体将被删除然后重新创建,而预期的行为是save 操作失败。

到目前为止,我已经看到了两种解决此问题的方法:

    使用@Version注解。找不到任何说明 Spring Data 支持使用版本化文档在 MongoDB 中进行乐观锁定的文档。如果有人能指出我的链接,将不胜感激。

    使用MongoOperations.findAndModify,如果返回null则失败。这种方法的缺点是我不能再将我的存储库 API 实现为具有“获取实体”和“保存更新的实体”类型的语义。例如:

    User user = userRepository.findByUsername("uniqueUsername");
    user.setLastName("Archer");
    userRepository.update(user);
    

我猜我必须将其中的一些推送到存储库:

userRepository.updateLastname("uniqueUsername", "Archer");

但我有点担心,如果我想做的每一种更新都需要新方法,我的存储库接口会变得无法控制。

我意识到我实际上还没有提出一个问题,所以这里是:使用 Spring Data for MongoDB 设计应用程序的最佳实践是什么?

【问题讨论】:

【参考方案1】:

在属性上使用@org.springframework.data.annotation.Version 应该可以解决问题。我创建了DATAMONGO-1275 来改进这方面的文档。

【讨论】:

如果我理解正确,这只会在更新时抛出 OptimisticLockException 对吗?是否也可以支持删除? docs.spring.io/spring-data/mongodb/docs/1.10.4.RELEASE/…文档链接 如果文档指定了要使用的版本注释的完全限定路径会更有帮助,最后在这里进行验证。

以上是关于如何在 Spring Data MongoDB 中使用乐观锁定?的主要内容,如果未能解决你的问题,请参考以下文章

在将它们添加到 MongoDB 之前,如何在 Spring Data 中处理插入请求?

如何在 Spring Data MongoDB 中使用乐观锁定?

Spring Data MongoDB:如何实现“实体关系”?

如何利用spring data mongodb 进行多条件查询

如何仅返回 Spring Data MongoDB 中查询的特定字段?

如何在带有自定义过滤器的 Spring Data mongodb 中使用分页和排序?