ConstraintViolationException最后不也抛出了,为什么没被catch到?

简介: ConstraintViolationException最后不也抛出了,为什么没被catch到?

上周,我们通过这篇文章《为什么catch了异常,但事务还是回滚了?》来解释了,之前test4为什么会回滚的原因。

但还是收到了很多没有理解的反馈,主要是根据前文给出的线索去跟踪,是获得到了回滚的标示和异常,而让大家不理解的是,javax.validation.ConstraintViolationException异常不是最后也向外抛出了,那么为什么test4里catch没有能够捕获到呢?

其实这个问题并不难解释,下面就通过这篇文章,做个小实验,帮助大家进一步理解大家的这个疑问!

如果你还不了解这篇文章在讨论什么,建议先看之前的两篇:

动手尝试一下

由于@Transactional注解的事务是通过切面来实现的,所以要通过源码去了解整个过程,可能还是不容易理解。

所以,这里教大家一个简单方法来理解这次test4的catch为什么没有捕获异常。

我们通过类似下面的方式,给test4多加一些日志信息和断点:

image.png

同时,记得也在上一篇说到的事务提交入口,也加上断点。

image.png

然后尝试触发test4的执行,通过DEBUG,我们都可以观察到:

test4中我们加的断点,除了47行没进入,其他的一次性都执行完了。然后才进入了org.springframework.orm.jpa.JpaTransactionManagerdoCommit方法。

所以,前文中我们跟踪的事务回滚所抛出的异常,其实是在test4中的try-catch块执行完之后才抛出的,所以内部的这个catch是无法捕获异常的,这里完全就是catch了个寂寞。

通过日志,我们也能观察到这样的执行顺序:

image.png

好了,通过这样来看,是不是要比之前有进一步的理解了呢?如果您还想跟深入的了解事务的底层运行机制,一定要debug一下源码,自己过一遍,理解会深刻哦!如果你还有其他疑问,欢迎加入我们的Spring技术交流群,参与交流与讨论,一起学习与进步!如果您正在学习Spring Boot,我的免费教程一直在持续连载,欢迎关注Spring Boot 2.x基础教程

目录
相关文章
|
5月前
|
C++
C++一分钟之—异常处理try-catch
【6月更文挑战第22天】C++异常处理机制,借助`try`、`catch`、`throw`管理错误,优雅处理异常,防止程序崩溃。`try`包围可能出错的代码,`catch`捕获异常,`throw`引发异常。基本结构是:`try-catch`块中,未捕获的异常将向上抛出。多`catch`块可按顺序捕获不同类型的异常。易错点包括忽视异常传播、不精确的`catch`和资源未清理。通过精确捕获、RAII技术和适当的异常策略,提升代码健壮性和效率。
39 1
|
Java 程序员 API
异常(中)创建自定义异常,throw,throws关键字抛出异常
异常(中)创建自定义异常,throw,throws关键字抛出异常
108 0
|
6月前
|
C++
C++异常处理try和throw以及catch的使用
C++异常处理try和throw以及catch的使用
|
6月前
|
监控 Java 程序员
详解Java中的异常体系结构(throw,throws,try-catch,finally,自定义异常)
详解Java中的异常体系结构(throw,throws,try-catch,finally,自定义异常)
138 0
16 # 实现 catch 方法
16 # 实现 catch 方法
54 0
|
Java 程序员 编译器
异常(Exception)
异常(Exception)
105 0
异常(Exception)
|
Java API Spring
RuntimeException和Exception的区别
RuntimeException和Exception的区别
203 0
|
JSON 安全 前端开发
替代try catch处理异常的优雅方式
替代try catch处理异常的优雅方式
|
安全 Java 数据库连接
Java中的异常处理详解(try、catch、finally、throw、throws)
Java中的异常处理详解(try、catch、finally、throw、throws)
304 1