Spring Data JPA 提供了 @Transactional
注解,用于声明事务边界。事务是一组操作,这些操作要么全部成功,要么全部失败,从而保证数据的一致性和完整性。
Spring 支持多种事务传播行为:
PROPAGATION_REQUIRED
:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。PROPAGATION_SUPPORTS
:支持当前事务,如果当前没有事务,就以非事务方式执行。PROPAGATION_MANDATORY
:使用当前的事务,如果当前没有事务,就抛出异常。PROPAGATION_REQUIRES_NEW
:新建事务,如果当前存在事务,把当前事务挂起。PROPAGATION_NOT_SUPPORTED
:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。PROPAGATION_NEVER
:以非事务方式执行,如果当前存在事务,则抛出异常。PROPAGATION_NESTED
:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED
类似的操作。在需要保证多个数据库操作的一致性时,可以使用 @Transactional
注解。例如,在转账操作中,需要同时更新两个账户的余额,这两个操作必须在同一个事务中进行。
@Transactional
注解未按顺序执行的原因可能有以下几种:
PROPAGATION_REQUIRES_NEW
,导致每个方法都在新的事务中执行,而不是在同一个事务中。假设有一个转账服务:
@Service
public class TransferService {
@Autowired
private AccountRepository accountRepository;
@Transactional(propagation = Propagation.REQUIRED)
public void transfer(String fromAccount, String toAccount, double amount) {
Account from = accountRepository.findById(fromAccount).orElseThrow(() -> new RuntimeException("Account not found"));
Account to = accountRepository.findById(toAccount).orElseThrow(() -> new RuntimeException("Account not found"));
from.setBalance(from.getBalance() - amount);
to.setBalance(to.getBalance() + amount);
accountRepository.save(from);
accountRepository.save(to);
}
}
在这个示例中,transfer
方法使用了 @Transactional(propagation = Propagation.REQUIRED)
,确保转账操作在一个事务中进行。
通过以上方法,可以确保 @Transactional
注解按预期顺序执行。
领取专属 10元无门槛券
手把手带您无忧上云