From e6249cd01c88415af3503f20b8d314c46d2ecadf Mon Sep 17 00:00:00 2001 From: bifurcated Date: Tue, 16 Jan 2024 14:53:09 +0300 Subject: [PATCH] Change update return Wallet this is fix concurrency update --- .../bifurcated/wallet/data/WalletRepo.java | 19 +++++++++++++++++++ .../wallet/service/WalletService.java | 18 ++---------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/bifurcated/wallet/data/WalletRepo.java b/src/main/java/com/bifurcated/wallet/data/WalletRepo.java index 431ff50..0a9c1ca 100644 --- a/src/main/java/com/bifurcated/wallet/data/WalletRepo.java +++ b/src/main/java/com/bifurcated/wallet/data/WalletRepo.java @@ -1,8 +1,27 @@ package com.bifurcated.wallet.data; +import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.repository.CrudRepository; +import java.util.Optional; import java.util.UUID; public interface WalletRepo extends CrudRepository { + + @Query(""" + UPDATE wallet + SET amount = (amount + :amount) + WHERE id = :id + RETURNING id, amount + """) + Optional updateAmount(UUID id, Float amount); + + @Query(""" + UPDATE wallet + SET amount = (amount - :amount) + WHERE id = :id + RETURNING id, amount + """) + Wallet updateAmountReduce(UUID id, Float amount); + } diff --git a/src/main/java/com/bifurcated/wallet/service/WalletService.java b/src/main/java/com/bifurcated/wallet/service/WalletService.java index 71c6195..50914e3 100644 --- a/src/main/java/com/bifurcated/wallet/service/WalletService.java +++ b/src/main/java/com/bifurcated/wallet/service/WalletService.java @@ -5,14 +5,8 @@ import com.bifurcated.wallet.errors.NotEnoughMoneyError; import com.bifurcated.wallet.errors.WalletNotFoundError; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.retry.annotation.Backoff; -import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; -import java.sql.SQLException; import java.util.UUID; @@ -25,25 +19,17 @@ public WalletService(WalletRepo walletRepo) { this.walletRepo = walletRepo; } - @Transactional( - isolation = Isolation.SERIALIZABLE, - propagation = Propagation.REQUIRES_NEW) - @Retryable(retryFor = SQLException.class, maxAttempts = 17, backoff = @Backoff(delay = 500)) public Wallet addAmount(UUID id, Float amount) { - var wallet = walletRepo.findById(id).orElseThrow(WalletNotFoundError::new); - wallet.setAmount(wallet.getAmount() + amount); - return walletRepo.save(wallet); + return walletRepo.updateAmount(id, amount).orElseThrow(WalletNotFoundError::new); } - @Transactional public Wallet reduceAmount(UUID id, Float amount) { var wallet = walletRepo.findById(id).orElseThrow(WalletNotFoundError::new); var reduce = wallet.getAmount() - amount; if (reduce < 0) { throw new NotEnoughMoneyError(wallet.getAmount(), amount); } - wallet.setAmount(reduce); - return walletRepo.save(wallet); + return walletRepo.updateAmountReduce(id, amount); } public Float amount(UUID id) {