欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > Spring Boot事务管理详解(附银行转账案例)

Spring Boot事务管理详解(附银行转账案例)

2025/4/2 21:31:30 来源:https://blog.csdn.net/weixin_62922042/article/details/146637080  浏览:    关键词:Spring Boot事务管理详解(附银行转账案例)

一、事务基础概念

事务的ACID特性

  • 原子性(Atomicity):操作要么全部成功,要么全部失败
  • 一致性(Consistency):数据在事务前后保持合法状态
  • 隔离性(Isolation):多个事务并发互不干扰
  • 持久性(Durability):事务提交后数据永久保存

二、Spring Boot事务实战

1. 环境准备

// Maven依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

2. 实体类定义

@Entity
public class Account {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String accountNumber;private BigDecimal balance;// 省略getter/setter
}@Entity
public class TransferLog {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String fromAccount;private String toAccount;private BigDecimal amount;// 省略getter/setter
}

3. Service层事务控制

@Service
public class BankService {@Autowiredprivate AccountRepository accountRepository;@Autowiredprivate TransferLogRepository transferLogRepository;// 核心事务方法@Transactional(rollbackFor = Exception.class)public void transferMoney(String fromAccNum, String toAccNum, BigDecimal amount) {// 1. 扣减转出账户Account fromAccount = accountRepository.findByAccountNumber(fromAccNum);fromAccount.setBalance(fromAccount.getBalance().subtract(amount));accountRepository.save(fromAccount);// 模拟异常(测试事务回滚)if(amount.compareTo(BigDecimal.ZERO) < 0) {throw new RuntimeException("转账金额不能为负数");}// 2. 增加转入账户Account toAccount = accountRepository.findByAccountNumber(toAccNum);toAccount.setBalance(toAccount.getBalance().add(amount));accountRepository.save(toAccount);// 3. 记录转账日志TransferLog log = new TransferLog();log.setFromAccount(fromAccNum);log.setToAccount(toAccNum);log.setAmount(amount);transferLogRepository.save(log);}
}

三、关键注解说明

@Transactional 参数解析:

@Transactional(isolation = Isolation.DEFAULT,    // 事务隔离级别propagation = Propagation.REQUIRED, // 传播行为rollbackFor = Exception.class,    // 指定回滚的异常类型timeout = 30                     // 事务超时时间(秒)
)

四、常见事务失效场景

  1. 非public方法@Transactional只能用于public方法
  2. 自调用问题:同一个类中方法A调用方法B(B有事务注解),事务不生效
  3. 异常被捕获:事务方法内捕获异常未重新抛出
  4. 错误异常类型:默认只回滚RuntimeException,需通过rollbackFor指定

五、事务传播机制示例

// 嵌套事务示例
@Transactional(propagation = Propagation.REQUIRED)
public void parentMethod() {// 主事务逻辑childMethod();  // 嵌套子事务
}@Transactional(propagation = Propagation.REQUIRES_NEW)
public void childMethod() {// 独立事务执行// 即使外层事务回滚,此方法仍会提交
}

六、事务验证测试

@SpringBootTest
class TransactionTest {@Autowiredprivate BankService bankService;@Testvoid testTransferSuccess() {// 正常转账测试bankService.transferMoney("A123", "B456", new BigDecimal("100.00"));// 验证账户余额和日志记录}@Testvoid testTransferRollback() {// 测试异常回滚assertThrows(RuntimeException.class, () -> {bankService.transferMoney("A123", "B456", new BigDecimal("-100.00"));});// 验证数据未修改}
}

最佳实践建议

  1. 事务方法尽量放在Service层
  2. 明确指定rollbackFor属性
  3. 避免长事务(复杂操作拆分为多个小事务)
  4. 结合@Transactional与数据库约束保证数据一致性

扩展学习

  • Spring官方文档:Transactions
  • 分布式事务解决方案:Seata、XA协议
  • 事务隔离级别深度解析(脏读/幻读/不可重复读)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词