我很难理解如何决定使用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注释?为什么?
答案 0 :(得分:4)
一般回答
查找定义实际事务的操作 - 在本例中为transfer
方法。此方法本身代表一个完整的事务,因此您应该将其标记为
@Transactional(propagation = REQUIRED)
您需要保护其他方法不会被错误地调出事务,因此注释它们是个好主意
@Transactional(propagation = MANDATORY)
确保只从某些正在运行的事务的上下文中调用它们。
特定于春天的答案
默认情况下,Spring使用代理对象来实现诸如事务之类的建议,以及自调用(在this
上调用的方法,无论是隐式还是显式),都不会通过代理对象)没有应用建议。这意味着Spring在这种情况下实际上不会对deduct
和deposit
方法强制执行建议,尽管它仍然可以防止它们被其他东西在事务外部调用。 AspectJ AOP模型需要额外的编译时步骤,但避免了自调用问题,并正确地将建议应用于所有方法调用。
答案 1 :(得分:0)
修改2+属性的每个方法都应该是@Transactional。即使你没有这种方法,我也准备给你转移资金的方法。