十二、嵌套事务回滚过头@Servicepublic class DemoService {@Autowiredprivate DemoTwoService demoTwoService;@Autowiredprivate DemoDao demoDao;public@Transactional(rollbackFor = Exception.class)publicvoid query(Demo demo) throws Exception{demoDao.save(demo);demoTwoService.save(demo);}}
原本只是希望回滚demoServise.save(),不回滚demoDao.save(demo);,但是这种情况两个都会被回滚,因为demoTwoService.save(demo);没有捕获异常,往上抛出,导致query进行回滚,所以同时回滚了两个
解决方法:
@Servicepublic class DemoService {@Autowiredprivate DemoTwoService demoTwoService;@Autowiredprivate DemoDao demoDao;public@Transactional(rollbackFor = Exception.class)publicvoid query(Demo demo) throws Exception{demoDao.save(demo);try {demoTwoService.save(demo);} finally {}}}
可以将内部嵌套事务放在try/catch中,并且不继续往上抛异常 。这样就能保证,如果内部嵌套事务中出现异常,只回滚内部事务,而不影响外部事务 。
十三、编程式事务上面的事务失效都是基于@Transactional注解的,我们把这种事务叫做:声明式事务 。
其实,spring还提供了另外一种创建事务的方式,即通过手动编写代码实现的事务,我们把这种事务叫做:编程式事务 。
@Servicepublic class DemoService {@Autowiredprivate TransactionTemplate transactionTemplate;@Transactional(rollbackFor = Exception.class)publicvoid query(Demo demo) throws Exception{transactionTemplate.execute((status -> {save(demo);return Boolean.TRUE;}));}@Transactionalpublic void save(Demo demo) {}}
在spring中为了支持编程式事务,专门提供了一个类:TransactionTemplate,在它的execute方法中,就实现了事务的功能 。
【Spring事务失效的各种场景】使用TransactionTemplate的编程式事务可以
• 避免由于spring aop问题,导致事务失效的问题 。
• 能够更小粒度的控制事务的范围 。
tips:关于本文举例的query加事务不太符合开发的要求,但是有点懒就不改了
推荐阅读
- 四大会计师事务所哪个待遇最好 四大会计师事务所
- SpringCloud gateway自定义请求的 httpClient
- 记一次SpringBoot启动异常,jar问题的排查分析
- 高速ETC设备显示“标签已失效”或者“非法拆卸”是怎么回事?
- Spring boot的logback配置
- 车祸事故|理想L9试驾车“断轴”、主动刹车失效?理想汽车回应
- 试驾|理想L9试驾事故 客户称“断轴”、主动刹车失效!理想高管回应
- |在管理中,人际关系和事务往来是很重要的
- SpringCloud OpenFeign 服务调用传递 token
- SpringBoot数据库管理 - 用flyway对数据库管理和迁移