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

我正在浏览 Spring Data MongoDB - 参考文档,我发现这些例子有点过于简单了.

I'm going through Spring Data MongoDB - Reference Documentation and I'm finding the examples to be a bit too simplistic.

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

In particular I'm trying to understand how to handle stale data in concurrent environments. For instance, imagine I have the following entity:

public class Person {

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

    [...]

}

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

Now if I use CrudRepository to save/update/remove my entities, then imagine a scenario in which two threads retrieve the same entity, one of them removes it, and the other one updates its lastname field. If the delete call completes before the save call then my entity will be removed and then re-created, when the expected behaviour would be for the save operation to fail.

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

So far I've seen two options for getting around this issue:

  1. 使用 @Version 注释.找不到任何说明 Spring Data 支持使用版本化文档在 MongoDB 中进行乐观锁定的文档.如果有人能指出我的链接,将不胜感激.
  2. 使用 MongoOperations.findAndModify 如果返回 null 则失败.这种方法的缺点是我不能再将我的存储库 API 实现为具有获取实体"和保存更新的实体"类型的语义.例如:

  1. Use @Version annotation. Could not find any documentation saying Spring Data supports optimistic locking in MongoDB using versioned documents. If anyone can point me to a link it'd be appreciated.
  2. Use MongoOperations.findAndModify and fail if it returns null. The downside to this approach is that I can no longer implement my repository API to have "get entity" and "save updated entity" kind of semantics. e.g.:

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

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

I would have to push some of this to the repository I guess:

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

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

But I'm a little bit worried my repository interfaces will grow uncontrollably if every type of update I want to do requires a new method.

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

I realise I haven't actually stated a question yet, so here it goes: what's the best-practice for designing an application using Spring Data for MongoDB?

推荐答案

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

Using @org.springframework.data.annotation.Version on a property should do the trick. I've created DATAMONGO-1275 to improve the documentation on that.

相关文章