智用指南
第二套高阶模板 · 更大气的阅读体验

事务处理注解使用方法:让程序出错也能自动回滚

发布时间:2025-12-27 07:41:47 阅读:109 次

你在开发系统时,有没有遇到过这种情况:转账操作中,扣钱成功了,但收款方却没收到?这种问题往往是因为程序执行到一半出错了,但前面的操作已经生效。这时候,事务处理就派上用场了。

什么是事务处理

简单说,事务就是一组操作要么全部成功,要么全部失败。就像去便利店买东西,付款和拿货得一起完成,少一个都不行。在编程里,我们常用“事务注解”来控制这一过程。

@Transactional 注解怎么用?

在 Spring 框架中,最常用的事务注解是 @Transactional。你只需要在方法或类上加上这个注解,框架就会自动管理事务的开启、提交和回滚。

比如写一个转账方法:

@Service
public class AccountService {

    @Autowired
    private AccountMapper accountMapper;

    @Transactional
    public void transferMoney(String from, String to, BigDecimal amount) {
        accountMapper.deduct(from, amount);
        accountMapper.add(to, amount);
    }
}

只要这个方法里有任何一步抛出异常,比如数据库连接失败或者金额为负,整个操作都会回滚,就像什么都没发生过。

哪些情况会触发回滚?

默认情况下,只有运行时异常(RuntimeException)和错误(Error)才会触发自动回滚。如果你抛的是检查异常(Exception 的子类但不是 RuntimeException),事务不会自动回滚。

比如你想在余额不足时手动回滚,可以这样写:

@Transactional
public void transferMoney(String from, String to, BigDecimal amount) throws InsufficientFundsException {
    if (getBalance(from).compareTo(amount) < 0) {
        throw new InsufficientFundsException("余额不足");
    }
    accountMapper.deduct(from, amount);
    accountMapper.add(to, amount);
}

这时候要让事务回滚,就得显式声明:

@Transactional(rollbackFor = Exception.class)
public void transferMoney(...) throws InsufficientFundsException { ... }

注意这些细节

事务注解不是加了就万事大吉。同一个类里的方法调用,如果不通过代理对象,事务可能不生效。比如 A 方法调用本类的 B 方法,而 B 加了 @Transactional,这时候事务很可能被忽略。

还有,事务只对数据库操作有效。如果你在方法里发邮件、上传文件,这些外部操作不会被事务管理,出错了也撤不回来。得自己额外处理。

另外,别忘了配置数据源支持事务。MySQL 用 InnoDB 引擎才行,MyISAM 就不行。就像你买了智能锁,结果门没装对,再高级也没用。