Loading... ## 声明式事务 ### 第一步: 首先我们需要在启动类中添加注解`@EnableTransactionManagement` ```java @SpringBootApplication @MapperScan("com.example.demo.mapper") @EnableTransactionManagement public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` ### 第二步: 我们在涉及多张表操作的方法上条件`@Transactional`注解,当方法中出现异常,在此方法中进行的任何操作都将回滚  ## 编程式事务 替换里面的业务代码,即可复用 ```java @Resource private PlatformTransactionManager transactionManager; public User getUserById(Integer id) { DefaultTransactionDefinition transactionDefinition = null; TransactionStatus transactionStatus = null; User user = null; try { // TODO 有事务,则使用当前事务;否则开启新事务 transactionDefinition = new DefaultTransactionDefinition(); transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); transactionStatus = transactionManager.getTransaction(transactionDefinition); // TODO 业务代码:涉及对多张表操作 // 查询id对应的user用户 user = this.getById(id); // 同时往product表中插入一条数据 final TProduct tProduct = new TProduct(); tProduct.setName("abc"); tProduct.setPrice(2); tProduct.setVersion(1); productService.insertProduct(tProduct); user.setProduct(tProduct); // TODO 事务提交 transactionManager.commit(transactionStatus); } catch (Exception e) { if (transactionStatus != null) { // TODO 出现异常事务回滚 transactionManager.rollback(transactionStatus); } throw new RuntimeException(e); } return user; } ``` ## 总结 ### 1、声明式事务的优点 <div class="tip inlineBlock success"> * 声明式事务可以帮助我们节省很多代码,他会自动进行事务的开启,提交和回滚等操作。 * 声明式事务是使用AOP实现的,本质就是在目标方法执行前后进行拦截。在目标方法执行前加入或创建事务,在目标执行后,根据实际情况选择提交或者回滚事务。 * 使用这种方法,对代码没有侵入性,在方法内只需要编写业务逻辑即可。 </div> ### 2.声明式事务的粒度问题 声明式事务有一个局限,那就是它最小粒度要作用到方法上。 <div class="tip inlineBlock error"> 错误的使用声明式事务可能带来隐患,比如RPC远程调用,RPC调用成功了,但是本地事务回滚了,导致RPC调用无法回滚;如果是编程式事务,那么在业务中就会清楚的看到什么地方开启了事务,什么地方提交了事务,什么地方回滚了事务。有人改动这段代码时候,就会强制他考虑要加的代码是否需要放在事务中。 </div> ### 3.声明式事务失效场景 <div class="tip inlineBlock error"> * 如果声明事务的方法不是public,事务会失效 * 同一个类中方法调用,事务嵌套,被调用方法事务失效 * 异常被try catch 捕获,事务失效 * 数据库引擎要支持事务,mysql数据库,必须设置数据库引擎为InnoDB。 * springboot是否开始事务管理,@EnableTransactionManagement(默认开启) * 异常类型配置错误 * 业务和spring事务代码必须在一个线程中 * 事务传播属性设置错误 </div> ### 最后: > 为了降低事故的发生,建议使用编程式事务。 最后修改:2023 年 01 月 25 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果文章有用,请随意打赏。