返回

编程式事务

后端

Spring实现事务的两种方式

在Spring项目中,事务管理是一个非常重要的概念。它可以确保我们的数据操作是原子性的,要么全部成功,要么全部失败。Spring提供了两种实现事务的方式:编程式事务和声明式事务。

编程式事务是通过在代码中显式地使用TransactionManager来管理事务。这种方式比较灵活,但需要程序员自己手动控制事务的开始、提交和回滚。

@Transactional
public void transferMoney(Long fromAccountId, Long toAccountId, BigDecimal amount) {
    // 获取事务管理器
    TransactionManager transactionManager = ...;

    // 创建一个新事务
    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());

    try {
        // 从fromAccountId账户扣钱
        Account fromAccount = accountDao.findById(fromAccountId);
        fromAccount.setBalance(fromAccount.getBalance().subtract(amount));
        accountDao.update(fromAccount);

        // 给toAccountId账户加钱
        Account toAccount = accountDao.findById(toAccountId);
        toAccount.setBalance(toAccount.getBalance().add(amount));
        accountDao.update(toAccount);

        // 提交事务
        transactionManager.commit(status);
    } catch (Exception e) {
        // 回滚事务
        transactionManager.rollback(status);
        throw e;
    }
}

声明式事务是通过在方法上添加@Transactional注解来实现的。这种方式更加简单,只需要在需要管理事务的方法上添加注解即可。

@Transactional
public void transferMoney(Long fromAccountId, Long toAccountId, BigDecimal amount) {
    // 从fromAccountId账户扣钱
    Account fromAccount = accountDao.findById(fromAccountId);
    fromAccount.setBalance(fromAccount.getBalance().subtract(amount));
    accountDao.update(fromAccount);

    // 给toAccountId账户加钱
    Account toAccount = accountDao.findById(toAccountId);
    toAccount.setBalance(toAccount.getBalance().add(amount));
    accountDao.update(toAccount);
}

项目中应该选择哪种方式

在实际项目中,应该根据具体情况选择使用哪种事务管理方式。如果需要对事务有更细粒度的控制,可以使用编程式事务;如果需要更简单、更方便的方式来管理事务,可以使用声明式事务。

通过源码结合图文分析spring实现事务的逻辑

Spring实现事务的逻辑比较复杂,这里仅简单介绍一下。Spring通过AOP技术在方法执行前后自动添加事务处理逻辑。当一个方法被调用时,Spring会先检查该方法是否添加了@Transactional注解。如果有,Spring就会创建一个TransactionManager对象,并使用该对象来管理事务。

Spring提供了多种TransactionManager实现,比如DataSourceTransactionManager、JtaTransactionManager等。这些实现分别对应不同的事务管理机制,比如JDBC事务、JTA事务等。

当TransactionManager创建完成后,Spring会创建一个TransactionStatus对象,并将其传递给被调用的方法。TransactionStatus对象包含了事务的状态信息,比如事务是否已经开始、是否已经提交或回滚等。

被调用的方法在执行过程中,如果发生异常,Spring会自动回滚事务;如果方法执行成功,Spring会自动提交事务。

总结

Spring提供了两种实现事务的方式:编程式事务和声明式事务。在实际项目中,应该根据具体情况选择使用哪种事务管理方式。Spring实现事务的逻辑比较复杂,通过AOP技术在方法执行前后自动添加事务处理逻辑。