正文
系列目录
一、引子
在Spring中,事务有两种实现方式:
- 编程式事务管理: 编程式事务管理使用底层源码可实现更细粒度的事务控制。spring推荐使用TransactionTemplate,典型的模板模式。
- 申明式事务管理: 添加@Transactional注解,并定义传播机制+回滚策略。基于Spring AOP实现,本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
二、简单样例
需求:
创建用户时,新建一个用户余额表。如果用户余额创建失败抛出异常,那么用户表也回滚,即要保证“新增用户+新增用户余额”一起成功 或 回滚。
2.1 申明式事务管理
如下图,只需要在service.impl层,业务方法上添加@Transactional注解,定义事务的传播机制为REQUIRED(不写这个参数,默认就是REQUIRED),遇到Exception异常就一起回滚。
REQUIRED传播机制下:存在加入事务,不存在创建新事务。保证了当前方法中的所有数据库操作都在一个物理事务中,当遇到异常时会整个业务方法一起回滚。
1 /** 2 * 创建用户并创建账户余额 3 * 4 * @param name 5 * @param balance 6 * @return 7 */ 8 @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class) 9 @Override 10 public void addUserBalanceAndUser(String name, BigDecimal balance) { 11 log.info("[addUserBalanceAndUser] begin!!!"); 12 //1.新增用户 13 userService.addUser(name); 14 //2.新增用户余额 15 UserBalance userBalance = new UserBalance(); 16 userBalance.setName(name); 17 userBalance.setBalance(new BigDecimal(1000)); 18 this.addUserBalance(userBalance); 19 log.info("[addUserBalanceAndUser] end!!!"); 20 }
2.2 编程式事务管理
编程式事务管理,我们使用Spring推荐的transactionTemplate。我这里因为使用的是spring cloud的注解配置,实现用了自动配置类配置好了TransactionTemplate这个类型的bean.使用的时候直接注入bean使用即可(当然老式的xml配置也是一样的)。如下:
1 /** 2 * 创建用户并创建账户余额(手动事务,不带结果) 3 * 4 * @param name 5 * @param balance 6 * @return 7 */ 8 @Override 9 public void addUserBalanceAndUserWithinTT(String name, BigDecimal balance) { 10 //实现一个没有返回值的事务回调 11 transactionTemplate.execute(new TransactionCallbackWithoutResult() { 12 @Override 13 protected void doInTransactionWithoutResult(TransactionStatus status) { 14 try { 15 log.info("[addUserBalanceAndUser] begin!!!"); 16 17 //1.新增用户 18 userService.addUser(name); 19 //2.新增用户余额 20 UserBalance userBalance = new UserBalance(); 21 userBalance.setName(name); 22 userBalance.setBalance(new BigDecimal(1000)); 23 userBalanceRepository.insert(userBalance); 24 log.info("[addUserBalanceAndUser] end!!!"); 25 //注意:这里catch住异常后,设置setRollbackOnly,否则事务不会滚。当然如果不需要自行处理异常,就不要catch了 26 } catch (Exception e) { 27 // 异常回滚 28 status.setRollbackOnly(); 29 log.error("异常回滚!,e={}",e); 30 } 31 32 } 33 }); 34 }
注意:
1.可以不用try catch,transactionTemplate.execute自己会捕捉异常并回滚。--》推荐
2.如果有业务异常需要特殊处理,记得:status.setRollbackOnly(); 标识为回滚。--》特殊情况才使用
三、总结
spring支持的这两种方式都可以,个人认为大部分情况下@Transactional可以满足需要。
------------------个人能力有限,大家多交流,一起壮哉我大JAVA!------------------
如果你觉得本文对你有点帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?