繁体   English   中英

Java,转帐服务和并发问题

[英]Java, Transfer money service and concurrency issue

我有这样的代码:

@Transactional(rollbackOn = RuntimeException.class)
    synchronized public void transfer(@NonNull final TransferModel transferModel) {
        log.info("Start processing money transfer from user: {} to receiver: {}. Transfer amount: {}", transferModel.getOwnerId(), transferModel
                .getReceiverId(), transferModel.getAmount());

        final AccountEntity ownerAccount = findByOwner(transferModel.getOwnerId());
        final AccountEntity receiverAccount = findByOwner(transferModel.getReceiverId());

        log.info("Owner balancer before transfer: {}. Receiver balance before transfer {}", ownerAccount.getBalance(), receiverAccount.getBalance());

        if (ownerAccount.getBalance().compareTo(transferModel.getAmount()) < 0) {
            throw new IllegalArgumentException("Owner has insufficient amount of money");
        }

        withdrawFromOwnerAccount(ownerAccount, transferModel.getAmount());
        depositToReceiverAccount(receiverAccount, transferModel.getAmount());

        log.info("Transfer money finished successful");
        log.info("Owner balancer after transfer: {}. Receiver balance after transfer {}", ownerAccount.getBalance(), receiverAccount.getBalance());
    }

一种简单的方法,可将所有者的零用钱传递给接收者。 这种解决方案很幼稚,因为它一次不能处理多个转移。 如何确保此方法将处理一个以上的请求并在并发环境中安全?

正如ghostCat所述,我们对您的环境并不熟悉,因此,如果任何“看起来很幼稚”的方法都有副作用,我们将一无所知。

也就是说,假设这是一个非常简单明了的代码,并且methods-names反映了它们在做什么,那么我认为我们不必同步所有方法,而仅同步关键部分:

withdrawFromOwnerAccount(ownerAccount, transferModel.getAmount());
depositToReceiverAccount(receiverAccount, transferModel.getAmount());

我们可以使用帐户同步此部分:

synchronized (ownerAccount) {
    withdrawFromOwnerAccount(ownerAccount, transferModel.getAmount());
}
synchronized (receiverAccount) {
    depositToReceiverAccount(receiverAccount, transferModel.getAmount());
}

这样,我们就可以并行执行此方法,并且仅当给定者/接收者已经在执行另一笔交易的过程中时才锁定线程。

注意:要应用此方法,您必须确保同一帐户没有两个对象!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM