相同方法与存储库上带有悲观锁的事务之间的竞争条件

问题描述 投票:0回答:1

我在确保转账方法是线程安全的方面遇到了问题。在账户类中,我有一组传入和传出转账。当从 A 到 B 的多个转账同时发生时,raceCondition 就会出现问题。

我尝试在帐户存储库上实现悲观锁,特别是在 findById 方法上,但竞争条件仍然可能发生。怎么解决这个问题呢?我应该直接在方法中而不是在存储库上加锁吗?或者也许采用乐观锁定?我浏览了过去的主题,发现悲观锁定比乐观锁定更适合此类用途。还是我错了?

public interface AccountRepository extends JpaRepository<Account, Long> {
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    Optional<Account> findById(Long accountId);
    }

    public interface TransferRepository extends JpaRepository<Transfer, Long>,     JpaSpecificationExecutor<Transfer> {
    }






    @Transactional
    public Transfer makeTransfer(CreateTransferCommand command) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String currentUsername = authentication.getName();

        Account sourceAccount = accountRepository.findById(command.getSourceAccountId())
                .orElseThrow(() -> new EntityNotFoundException("Source account not found"));
        if (!sourceAccount.getUsername().equals(currentUsername)) {
            throw new WrongOwnerException("User does not own the source account");
        }

        Account destinationAccount = accountRepository.findById(command.getDestinationAccountId())
                .orElseThrow(() -> new EntityNotFoundException("Destination account not found"));
        if (sourceAccount.getBalance().compareTo(command.getAmount()) < 0) {
            throw new NotEnoughMoneyException("Source account does not have enough balance");
        }

        sourceAccount.setBalance(sourceAccount.getBalance().subtract(command.getAmount()));
        destinationAccount.setBalance(destinationAccount.getBalance().add(command.getAmount()));

        Transfer transfer = new Transfer();
        transfer.setSourceAccount(sourceAccount);
        transfer.setDestinationAccount(destinationAccount);
        transfer.setAmount(command.getAmount());
        transfer.setTitle(command.getTitle());
        transfer.setTransferDate(LocalDateTime.now());

        return transferRepository.save(transfer);
    }
java spring-boot transactions race-condition pessimistic-locking
1个回答
0
投票

告诉我你是如何解决这个问题的,因为我也有同样的问题! :D

© www.soinside.com 2019 - 2024. All rights reserved.