Java Spring数据-MongoDb-What';如果我更新两次相同的文档,就会发生这种情况

Java Spring数据-MongoDb-What';如果我更新两次相同的文档,就会发生这种情况,java,spring,mongodb,spring-boot,spring-data-mongodb,Java,Spring,Mongodb,Spring Boot,Spring Data Mongodb,我在MongoDB 3.6.2中使用SpringBoot 2.1.10和SpringData 我有一个@Service类,该类具有以下业务逻辑,用于保留通用凭证文档: public Voucher reserveVoucher() { Voucher voucherToReserve = voucherRepository.findFirstByStatusEquals(VoucherStatus.ACTIVE) .orElseThrow(() -> new Ba

我在MongoDB 3.6.2中使用SpringBoot 2.1.10和SpringData

我有一个
@Service
类,该类具有以下业务逻辑,用于保留通用凭证文档:

public Voucher reserveVoucher() {
     Voucher voucherToReserve = voucherRepository.findFirstByStatusEquals(VoucherStatus.ACTIVE)
        .orElseThrow(() -> new BadRequestException("VOUCHER_NOT_FOUND", "Voucher with status ACTIVE not found"));

     voucherToBeConsume.setStatus(VoucherStatus.RESERVED);
     voucherToBeConsume.setUserId(voucherConsumer.getUserId());

     return voucherRepository.save(voucherToBeConsume);
}
我知道Spring中的
@Service
类默认为
Singleton

如果
findfirstbystatues
方法检索同一个文档,并且在
save
方法执行两次之后,在有更多服务器的环境中会发生什么情况?文档更新两次或第二次更新失败?

即使在一台服务器上,也可以由两个不同的线程同时调用服务,例如通过两个并发REST调用

在MongoDB中,不能使用SELECT之类的行锁。。。用于事务数据库中的更新。 因此,在您的情况下,文档可能会更新两次

但是,您可以通过条件更新模拟行锁:

UpdateResult updateResult = mongoTemplate.updateFirst(
  query(
    where("_id").is(voucherToReserve.getId())
     .and("status").is(VoucherStatus.ACTIVE)
  ), 
  new Update()
    .set("status", VoucherStatus.RESERVED)
    .set("userId", userId),
  Voucher.class
);  
if(updateResult.getModifiedCount() != 1){
  throw ...
}

另请参见

非常感谢您消除我的疑虑,您的建议很有效!