0

我很难理解如何决定用 Spring @Transaction 注释哪些方法。

BankService {

    transfer(Account from, Account to, int amount){
        deduct(from, amount);
        deposit(to, amount);
    }

    deduct(Account account, int amount){
        account = accountRepo.load(account); //make sure we dont have an old reference with old balance            
        int balance = account.getBalance();
        if (balance<amount){
            throw new IllegalStateException("Not enough money");
        } else {
            account.setBalance(balance-amount);
            accountRepo.save(account);
        }
    }

    deposit(Account account, int amount){
        account = accountRepo.load(account); //make sure we dont have an old reference with old balance
        account.setBalance(account.getBalance() + amount);
        accountRepo.save(account);
    }

}

在一次转账中,如果扣款失败,那么即使存款没有失败,显然也不应该继续扣款。

在五种方法(转账、扣款、存款、加载、保存)中,哪些应该用@Transactional 注释,为什么?

4

2 回答 2

4

一般回答

寻找定义实际事务的操作——在本例中是transfer方法。这个方法本身就代表了一个完整的交易,所以你应该标记它

@Transactional(propagation = REQUIRED)

您需要保护其他方法不被错误地从事务中调用,因此最好对它们进行注释

@Transactional(propagation = MANDATORY)

以确保仅从某些正在运行的事务的上下文中调用它们。

春季特定的答案

默认情况下,Spring 使用代理对象来实现诸如事务之类的建议,而自调用this隐式或显式调用的方法,不通过代理对象)没有应用建议。这意味着在这种情况下,Spring 实际上不会强制执行关于deductanddeposit方法的建议,尽管它仍然会保护它们不被其他东西在事务之外调用。AspectJ AOP 模型需要一个额外的编译时步骤,但避免了自调用问题并正确地将建议应用于所有方法调用。

于 2013-10-24T04:34:28.370 回答
0

每个修改 2+ 属性的方法都应该是 @Transactional。我正要给你举个例子,转账的方法,即使你没有。

于 2013-10-24T04:34:01.047 回答