异常代码

下面代码为了测试统一写在方法上

@GetMapping("testOne")@Transactional()public PTreeFolder testOne() {PTreeFolder insertData1=new PTreeFolder();String guid1=java.util.UUID.randomUUID().toString();insertData1.setFolderId(guid1);insertData1.setName("12");PTreeFolder p1= this.pTreeFolderService.insert(insertData1);PTreeFolder pData =this.pTreeFolderService.queryById(guid1);PTreeFolder insertData2=new PTreeFolder();String guid2=java.util.UUID.randomUUID().toString();//insertData2.setFolderId(guid2);insertData2.setName("12");PTreeFolder p2= this.pTreeFolderService.insert(insertData2);return p2;
}

断点调试

进异常

结果分析:

p1是正常数据,p2缺少主键,执行以后走了异常,数据pData是查询的值,注意异常之前是可以查询到的,这个时候数据库是不存储数据的(包括p1)。

执行完成以后报500,数据库存储了0条记录。

结果就是看到数据回滚了。

Catch如何处理

@GetMapping("testOne")@Transactional()public PTreeFolder testOne() {try {PTreeFolder insertData1=new PTreeFolder();String guid1=java.util.UUID.randomUUID().toString();insertData1.setFolderId(guid1);insertData1.setName("12");PTreeFolder p1= this.pTreeFolderService.insert(insertData1);PTreeFolder pData =this.pTreeFolderService.queryById(guid1);PTreeFolder insertData2=new PTreeFolder();String guid2=java.util.UUID.randomUUID().toString();//insertData2.setFolderId(guid2);insertData2.setName("12");PTreeFolder p2= this.pTreeFolderService.insert(insertData2);return p2;} catch (Exception e) {e.printStackTrace();return null;}}

执行以后

也就是说不会回滚。

分析

触发Transactional的回滚 需要RunTimeException异常。

如果要在抛出 非RuntimeException时也触发回滚机制,需要我们在注解上添加 rollbackFor = { Exception.class }属性。

@Transactional(rollbackFor = { Exception.class })

Try catch 以后异常被catch捕获不会触发Transactional的回滚。

解决

1、@ Transactional +catch中抛出RuntimeException异常

@GetMapping("testOne")@Transactional()public PTreeFolder testOne() {try {PTreeFolder insertData1=new PTreeFolder();String guid1=java.util.UUID.randomUUID().toString();insertData1.setFolderId(guid1);insertData1.setName("12");PTreeFolder p1= this.pTreeFolderService.insert(insertData1);PTreeFolder pData =this.pTreeFolderService.queryById(guid1);PTreeFolder insertData2=new PTreeFolder();String guid2=java.util.UUID.randomUUID().toString();//insertData2.setFolderId(guid2);insertData2.setName("12");PTreeFolder p2= this.pTreeFolderService.insert(insertData2);return p2;} catch (Exception e) {e.printStackTrace();throw  new RuntimeException();}
}

2、@Transactional(rollbackFor = { Exception.class }) 加上 catch中throw e

@GetMapping("testOne")@Transactional(rollbackFor = { Exception.class })public PTreeFolder testOne() {try {PTreeFolder insertData1=new PTreeFolder();String guid1=java.util.UUID.randomUUID().toString();insertData1.setFolderId(guid1);insertData1.setName("12");PTreeFolder p1= this.pTreeFolderService.insert(insertData1);PTreeFolder pData =this.pTreeFolderService.queryById(guid1);PTreeFolder insertData2=new PTreeFolder();String guid2=java.util.UUID.randomUUID().toString();//insertData2.setFolderId(guid2);insertData2.setName("12");PTreeFolder p2= this.pTreeFolderService.insert(insertData2);return p2;} catch (Exception e) {e.printStackTrace();throw e;}  }

3、直接回滚

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

代码

@GetMapping("testOne")@Transactional()public PTreeFolder testOne() {try {PTreeFolder insertData1 = new PTreeFolder();String guid1 = java.util.UUID.randomUUID().toString();insertData1.setFolderId(guid1);insertData1.setName("12");PTreeFolder p1 = this.pTreeFolderService.insert(insertData1);PTreeFolder pData = this.pTreeFolderService.queryById(guid1);PTreeFolder insertData2 = new PTreeFolder();String guid2 = java.util.UUID.randomUUID().toString();//insertData2.setFolderId(guid2);insertData2.setName("12");PTreeFolder p2 = this.pTreeFolderService.insert(insertData2);return p2;} catch (Exception e) {e.printStackTrace();TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();PTreeFolder resultData3 = new PTreeFolder();resultData3.setName("ddd");return resultData3;}}

推荐写法

@GetMapping("testOne")public PTreeFolder testOne() {return  this.pTreeFolderService.updateTest();
}

在Service中添加方法

@Transactional()@Overridepublic PTreeFolder updateTest(){try {PTreeFolder insertData1 = new PTreeFolder();String guid1 = java.util.UUID.randomUUID().toString();insertData1.setFolderId(guid1);insertData1.setName("12");PTreeFolder p1 = insert(insertData1);PTreeFolder pData = queryById(guid1);PTreeFolder insertData2 = new PTreeFolder();String guid2 = java.util.UUID.randomUUID().toString();//insertData2.setFolderId(guid2);insertData2.setName("12");PTreeFolder p2 = insert(insertData2);return p2;} catch (Exception e) {e.printStackTrace();TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();PTreeFolder resultData3 = new PTreeFolder();resultData3.setName("ddd");return resultData3;}}

@Transactional的使用相关推荐

  1. @Transactional注解最容易忽视的三个失效场景!

    @Transactional注解在以下场景中使用,是会失效的,切记! 1.非public方法 spring对注解事务的方法进行校验,修饰符是不是public,不是 public则不会获取@Transa ...

  2. 3 种场景 @Transactional 失效的解决方法

    以下文章来源方志朋的博客,回复"666"获面试宝典 来源 | blog.csdn.net/qq_20597727/article/details/84900994 Transact ...

  3. Spring官方都推荐使用的@Transactional事务,为啥我不建议使用!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 事务管理在系统开发中是不可缺少的一部分,Spring提供了 ...

  4. @aspect注解类不生效_springboot:@Transactional注解 VS @Service注解

    1. Transactional注解与Service/Component注解冲突? 之前遇到一个神奇的事情--用Transactional注解的方法,数据处理了一半,后面的数据处理抛出异常后,没有回滚 ...

  5. Spring Transactional还能导致生产事故?

    在Spring中进行事务管理非常简单,只需要在方法上加上注解@Transactional,Spring就可以自动帮我们进行事务的开启.提交.回滚操作.甚至很多人心里已经将Spring事务与@Trans ...

  6. 一口气说出 6 种 @Transactional 注解的失效场景

    一.事务 事务管理在系统开发中是不可缺少的一部分,Spring提供了很好事务管理机制,主要分为编程式事务和声明式事务两种. 编程式事务:是指在代码中手动的管理事务的提交.回滚等操作,代码侵入性比较强, ...

  7. Spring_Spring@Transactional

    Spring事务的传播行为 在service类前加上@Transactional,声明这个service所有方法需要事务管理.每一个业务方法开始时都会打开一个事务. Spring默认情况下会对运行期例 ...

  8. Spring 事务之@Transactional

    在业务代码中,有如下两种情况,比如: throw new RuntimeException("xxxxxxxxxxxx"); 事务回滚 throw new Exception(&q ...

  9. spring@Transactional注解事务不回滚不起作用无效的问题处理

    这几天在项目里面发现我使用@Transactional注解事务之后,抛了异常居然不回滚.后来终于找到了原因. 如果你也出现了这种情况,可以从下面开始排查. 一.特性 先来了解一下@Transactio ...

  10. SpringBoot之事务管理Transactional

    以前学ssh ssm都有事务管理service层通过applicationContext.xml配置,所有service方法都加上事务操作: 用来保证一致性,即service方法里的多个dao操作,要 ...

最新文章

  1. 经典的”服务器最多65536个连接”误解
  2. LIbGDX 示例Tests详解一:AccelerometerTest
  3. 3DSlicer14:Loadable Module
  4. juqery代码优化
  5. android UI布局
  6. Linux的逻辑卷状态不可用,linux – 逻辑卷在引导时处于非活动状态
  7. 使用Travis CI自动部署Hexo博客
  8. C++伪(pseudo)随机数生成及简单应用
  9. 华翼宽带android客户端,太凶残了:电信推华翼宽带专门防蹭网
  10. python数据分析学什么意思_什么是python数据分析
  11. 【Proteus仿真】PCF8591 AD电压采集8X8点阵显示
  12. opencv 表示图像的IplImage
  13. html不支持lang属性,html的lang属性学习笔记
  14. 【Web】CSS(No.33)Css页面布局经典案例(三)《京东首页》
  15. 好汉歌计算机音乐,好汉歌歌曲赏析
  16. 云和恩墨大讲堂 | 基于PCIE 闪存卡的 Oracle 数据库使用
  17. Elasticsearch 摄取节点(Ingest Node)使用Pipeline预处理文档
  18. Unraid搭建gitlab
  19. 计算机组成原理实验四 微程序控制器实验报告
  20. 关于MDL的一些事(2)

热门文章

  1. [乐意黎原创] 怎样计算多少英寸的显示器或电视机的实际长度和宽度
  2. 【每日论文】Journal of medical Internet research-期刊-数字校园社交网络方向
  3. 十年磨剑ADAMOracle正式部署BSC届时在DODO开始交易
  4. Windows修改C盘下的用户(Users)文件夹下的汉字文件夹
  5. c语言编程1 1=2,编写一个C语言程序:求S=1/1+1/2+1/3+…+1/n
  6. 捐款去了!支援灾区人民啊!!!
  7. 学php丢人吗,大学里一个人吃饭很丢人吗? - 窗外事 - 简单学习网论坛_中高考学习交流论坛_中学生学习论坛 - Powered by phpwind...
  8. [Code Jam] Millionaire
  9. 【Linux】进程概念(下篇) —— 程序地址空间详解
  10. Linux-groups