Skip to content

Commit

Permalink
Change update return Wallet
Browse files Browse the repository at this point in the history
this is fix concurrency update
  • Loading branch information
bifrurcated committed Jan 16, 2024
1 parent fa76637 commit e6249cd
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 16 deletions.
19 changes: 19 additions & 0 deletions src/main/java/com/bifurcated/wallet/data/WalletRepo.java
Original file line number Diff line number Diff line change
@@ -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<Wallet, UUID> {

@Query("""
UPDATE wallet
SET amount = (amount + :amount)
WHERE id = :id
RETURNING id, amount
""")
Optional<Wallet> updateAmount(UUID id, Float amount);

@Query("""
UPDATE wallet
SET amount = (amount - :amount)
WHERE id = :id
RETURNING id, amount
""")
Wallet updateAmountReduce(UUID id, Float amount);

}
18 changes: 2 additions & 16 deletions src/main/java/com/bifurcated/wallet/service/WalletService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;


Expand All @@ -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) {
Expand Down

0 comments on commit e6249cd

Please sign in to comment.