Spring @Transaction

时间:2013-10-24 04:28:31

标签: java spring transactions spring-transactions

我很难理解如何决定使用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注释?为什么?

2 个答案:

答案 0 :(得分:4)

一般回答

查找定义实际事务的操作 - 在本例中为transfer方法。此方法本身代表一个完整的事务,因此您应该将其标记为

@Transactional(propagation = REQUIRED)

您需要保护其他方法不会被错误地调出事务,因此注释它们是个好主意

@Transactional(propagation = MANDATORY)

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

特定于春天的答案

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

答案 1 :(得分:0)

修改2+属性的每个方法都应该是@Transactional。即使你没有这种方法,我也准备给你转移资金的方法。