Spring 数据 - MongoDb - 如果我更新两次相同的文档会发生什么



我在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。如果findFirstByStatusEquals方法检索同一个Document,并且在save方法执行两次之后,在有更多服务器的环境中会发生什么?文档更新两次还是第二次更新失败?

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

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

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

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 ...
}

另请参阅https://www.mongodb.com/blog/post/how-to-select--for-update-inside-mongodb-transactions

最新更新