企业网络推广网站建设西安云英网站建设
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:11
当前位置: 首页 > news >正文
企业网络推广网站建设,西安云英网站建设,网站的站点建设分为,舆情服务网站Spring之事务底层源码解析 1、EnableTransactionManagement工作原理 开启 Spring 事务本质上就是增加了一个 Advisor#xff0c;当我们使用 EnableTransactionManagement 注解来开启 Spring 事务时#xff0c;该注解代理的功能就是向 Spring 容器中添加了两个 Bean#xf…Spring之事务底层源码解析 1、EnableTransactionManagement工作原理 开启 Spring 事务本质上就是增加了一个 Advisor当我们使用 EnableTransactionManagement 注解来开启 Spring 事务时该注解代理的功能就是向 Spring 容器中添加了两个 Bean 1、AutoProxyRegistrar 2、ProxyTransactionManagementConfiguration AutoProxyRegistrar 主要的作用是向 Spring 容器中注册了一个 InfrastructureAdvisorAutoProxyCreator *的 Bean。 而 InfrastructureAdvisorAutoProxyCreator 继承了 AbstractAdvisorAutoProxyCreator所以这个类的主要作用就是开启自动代理也就是一个BeanPostProcessor它会在初始化之后去寻找 Advisor 类型的 Bean并判断当前某个 Bean 是否有匹配的 Advisor是否需要利用动态代理产生一个代理对象。 ProxyTransactionManagementConfiguration 是一个配置类它又定义了另外三个 bean 1、BeanFactoryTransactionAttributeSourceAdvisor一个 Advisor 2、AnnotationTransactionAttributeSource相当于 BeanFactoryTransactionAttributeSourceAdvisor 中的 Pointcut 3、TransactionInterceptor相当于 BeanFactoryTransactionAttributeSourceAdvisor 中的 Advice AnnotationTransactionAttributeSource 就是用来判断某个类上是否存在 Transactional 注解或者判断某个方法上是否存在 Transactional 注解的。 TransactionInterceptor 就是代理逻辑当某个类中存在 Transactional 注解时就会产生一个代理对象作为 Bean代理对象在执行某个方法时最终就会进入到 TransactionInterceptor 的 invoke() 方法。 2、Spring事务基本执行原理 一个 Bean 在执行 Bean 的创建生命周期时会经过 InfrastructureAdvisorAutoProxyCreator 的初始化后的方法会判断当前 Bean 对象是否和 BeanFactoryTransactionAttributeSourceAdvisor 匹配匹配逻辑为判断该 Bean 的类上是否存在 Transactional 注解或者类中的某个方法上是否存在 Transactional 注解如果存在则表示该 Bean 需要进行动态代理产生一个代理对象作为 Bean 对象。 该代理对象在执行某个方法时会再次判断当前执行的方法是否和 BeanFactoryTransactionAttributeSourceAdvisor 匹配如果匹配则执行该 Advisor 中的 TransactionInterceptor 的 invoke() 方法基本执行流程为 1、利用所配置的 PlatformTransactionManager 事务管理器新建一个数据库连接 2、修改数据库连接的 AutoCommit 为 false 3、执行 MethodInvocation.proceed() 方法简单理解就是执行业务方法其中就会执行 sql 语句 4、如果没有抛异常则提交 5、如果抛了异常则回滚 3、Spring事务详细执行流程 Spring事务执行流程图https://www.processon.com/view/link/5fab6edf1e0853569633cc06 4、Spring事务传播机制 在开发过程中经常会出现一个方法调用另外一个方法的情况那么这里就涉及到了多种场景比如 a() 调用 b() 1、a() 和 b() 方法中的所有 sql 需要在同一个事务中吗 2、a() 和 b() 方法需要单独的事务吗 3、a() 方法需要在事务中执行b() 方法还需要在事务中执行吗 4、等等情况… 所以这就要求 Spring 事务能支持上面各种场景这就是 Spring 事务传播机制的由来。那 Spring 事务传播机制是如何实现的呢? 先来看上述几种场景中的一种情况a() 在一个事务中执行调用 b() 方法时需要新开一个事务执行 1、首先代理对象执行 a() 方法前先利用事务管理器新建一个数据库连接 a 2、将数据库连接 a 的 autocommit 改为 false 3、把数据库连接 a 设置到 ThreadLocal 中 4、执行 a() 方法中的 sql 语句 5、执行 a() 方法过程中调用了 b() 方法注意这里要用代理对象调用 b() 方法 代理对象执行 b() 方法前判断出来了当前线程中已经存在一个数据库连接 a 了表示当前线程其实已经拥有一个 Spring 事务了则进行挂起挂起就是把 ThreadLocal 中的数据库连接 a 从 ThreadLocal 中移除并放入一个挂起资源对象中挂起完成后再次利用事务管理器新建一个数据库连接 b将数据库连接 b 的 autocommit 改为 false把数据库连接 b 设置到 ThreadLocal 中执行 b() 方法中的 sql 语句b() 方法正常执行完则从 ThreadLocal 中拿到数据库连接 b 进行提交提交之后就会恢复所挂起的数据库连接 a这里的恢复其实只是把在挂起资源对象中所保存的数据库连接 a 再次设置到 ThreadLocal 中 6、a() 方法正常执行完则从 ThreadLocal 中拿到数据库连接 a 进行提交 这个过程中最为核心的是在执行某个方法时判断当前是否已经存在一个事务就是判断当前线程的 ThreadLocal 中是否存在一个数据库连接对象如果存在则表示已经存在一个事务了。 5、Spring事务传播机制分类 其中以非事务方式运行表示以非 Spring 事务运行表示在执行这个方法时Spring 事务管理器不会去创建数据库连接执行 sql 语句时由 MyBatis 或JdbcTemplate 自己建立数据库连接来执行 sql。 情况一 Component public class UserService {Autowiredprivate UserService userService;Transactionalpublic void test() {// test方法中的sqluserService.a();}Transactionalpublic void a() {// a方法中的sql}}默认情况下传播机制为 REQUIRED表示当前如果没有事务则新建一个事务如果有事务则在当前事务中执行。 所以上面这种情况的执行流程如下 1、新建一个数据库连接 conn 2、设置 conn 的 autocommit 为 false 3、执行 test 方法中的 sql 4、执行 a 方法中的 sql 5、执行 conn 的 commit() 方法进行提交 情况二 Component public class UserService {Autowiredprivate UserService userService;Transactionalpublic void test() {// test方法中的sqluserService.a();int result 100 / 0;}Transactionalpublic void a() {// a方法中的sql}}所以上面这种情况的执行流程如下 1、新建一个数据库连接 conn 2、设置 conn 的 autocommit 为 false 3、执行 test 方法中的 sql 4、执行 a 方法中的 sql 5、抛出异常 6、执行 conn 的 rollback() 方法进行回滚所以两个方法中的 sql 都会回滚掉 情况三 Component public class UserService {Autowiredprivate UserService userService;Transactionalpublic void test() {// test方法中的sqluserService.a();}Transactionalpublic void a() {// a方法中的sqlint result 100 / 0;}}所以上面这种情况的执行流程如下 1、新建一个数据库连接 conn 2、设置 conn 的 autocommit 为 false 3、执行 test 方法中的 sql 4、执行 a 方法中的 sql 5、抛出异常 6、执行 conn 的 rollback() 方法进行回滚所以两个方法中的 sql 都会回滚掉 情况四 Component public class UserService {Autowiredprivate UserService userService;Transactionalpublic void test() {// test方法中的sqluserService.a();}Transactional(propagation Propagation.REQUIRES_NEW)public void a() {// a方法中的sqlint result 100 / 0;}}所以上面这种情况的执行流程如下 1、新建一个数据库连接 conn 2、设置 conn 的 autocommit 为 false 3、执行 test 方法中的 sql 4、又新建一个数据库连接 conn2 5、执行 a 方法中的 sql 6、抛出异常 7、执行 conn2 的 rollback() 方法进行回滚 8、继续抛异常对于 test() 方法而言它会接收到一个异常然后抛出 9、执行 conn 的 rollback() 方法进行回滚最终还是两个方法中的 sql 都回滚了 6、Spring事务强制回滚 正常情况下a() 调用 b() 方法时如果 b() 方法抛了异常但是在 a() 方法中捕获了那么 a() 方法的事务还是会正常提交的。但是有的时候我们捕获异常可能仅仅只是不把异常信息返回给客户端而是为了返回一些更友好的错误信息在这个时候我们还是希望事务能回滚的那这个时候就得告诉 Spring 把当前事务回滚掉做法就是 Transactional public void test(){// 执行sqltry {b();} catch (Exception e) {// 构造友好的错误信息返回TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); // 强制回滚}}public void b() throws Exception {throw new Exception(); }7、TransactionSynchronization Spring 事务有可能会提交、回滚、挂起、恢复所以 Spring 事务提供了一种机制可以让程序员来监听当前 Spring 事务所处的状态。 Component public class UserService {Autowiredprivate JdbcTemplate jdbcTemplate;Autowiredprivate UserService userService;Transactionalpublic void test() {TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {/ 事务挂起时执行该方法/Overridepublic void suspend() {System.out.println(test被挂起了);}/** 挂起恢复时执行该方法/Overridepublic void resume() {System.out.println(test被恢复了);}/** 提交之前执行该方法/Overridepublic void beforeCommit(boolean readOnly) {System.out.println(test准备要提交了);}/** 完成之前执行该方法/Overridepublic void beforeCompletion() {System.out.println(test准备要提交或回滚了);}/** 提交之后执行该方法/Overridepublic void afterCommit() {System.out.println(test提交成功了);}/** 完成之后执行该方法/Overridepublic void afterCompletion(int status) {System.out.println(test提交或回滚成功了);}});jdbcTemplate.execute(insert into t1 values(1,1,1,1,1));System.out.println(test);userService.a();}Transactional(propagation Propagation.REQUIRES_NEW)public void a() {TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {/** 事务挂起时执行该方法/Overridepublic void suspend() {System.out.println(a被挂起了);}/** 挂起恢复时执行该方法/Overridepublic void resume() {System.out.println(a被恢复了);}/** 提交之前执行该方法/Overridepublic void beforeCommit(boolean readOnly) {System.out.println(a准备要提交了);}/** 完成之前执行该方法/Overridepublic void beforeCompletion() {System.out.println(a准备要提交或回滚了);}/** 提交之后执行该方法/Overridepublic void afterCommit() {System.out.println(a提交成功了);}/** 完成之后执行该方法*/Overridepublic void afterCompletion(int status) {System.out.println(a提交或回滚成功了);}});jdbcTemplate.execute(insert into t1 values(2,2,2,2,2));System.out.println(a);}}
- 上一篇: 企业网络建站品牌建设是指什么
- 下一篇: 企业网络推广做网站推广公司网站整站下载带数据库后台的方法
相关文章
-
企业网络建站品牌建设是指什么
企业网络建站品牌建设是指什么
- 技术栈
- 2026年03月21日
-
企业外贸网站拓者设计官网网页版
企业外贸网站拓者设计官网网页版
- 技术栈
- 2026年03月21日
-
企业所得税税率5% 10% 25%深圳网站seo教程
企业所得税税率5% 10% 25%深圳网站seo教程
- 技术栈
- 2026年03月21日
-
企业网络推广做网站推广公司网站整站下载带数据库后台的方法
企业网络推广做网站推广公司网站整站下载带数据库后台的方法
- 技术栈
- 2026年03月21日
-
企业网页设计模板图片专业网站优化外包
企业网页设计模板图片专业网站优化外包
- 技术栈
- 2026年03月21日
-
企业网站 多网站推广源码搭建app教程
企业网站 多网站推广源码搭建app教程
- 技术栈
- 2026年03月21日






