【spring源码学习】spring的事务管理的源码解析

简介: 【一】spring事务管理(1)spring的事务管理,是基于aop动态代理实现的。对目标对象生成代理对象,加入事务管理的核心拦截器==>org.springframework.transaction.interceptor.TransactionInterceptor。

【一】spring事务管理
(1)spring的事务管理,是基于aop动态代理实现的。对目标对象生成代理对象,加入事务管理的核心拦截器==>org.springframework.transaction.interceptor.TransactionInterceptor。
===>spring事务管理的核心拦截器
===>需要配置的数据项:事务管理机制配置属性的查找类transactionAttributeSource,事务管理的核心处理器PlatformTransactionManager(如果能配置就配置,不能配置就从beanFactory中根据接口拿)

(2)实现事务管理需要配置事务管理处理器(事务处理的支持抽象封装(获取事务状态,提交事务,回归事务),如下是spring事务管理器的基础类。
==>org.springframework.transaction.PlatformTransactionManager
==>org.springframework.transaction.support.AbstractPlatformTransactionManager

(3)获取将要执行的方法的事务策略的配置信息的查询器。
==>org.springframework.transaction.interceptor.TransactionAttributeSource
==>org.springframework.transaction.annotation.AnnotationTransactionAttributeSource(基于注解进行事务管理配置的属性获取器)
==>该类内部也做属性配置缓存。以要执行的方法的对象Method method,和要执行的bean的Class<?> targetClass组装成org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.DefaultCacheKey.该类重写了equals和hashCode方法。


(4)spring事务管理的配置属性的实体类
==>org.springframework.transaction.interceptor.TransactionAttribute
==>org.springframework.transaction.interceptor.DefaultTransactionAttribute(spring的默认)
==>org.springframework.transaction.interceptor.RuleBasedTransactionAttribute(基于注解的事务管理配置属性的类)
==>其实就是,事务的传播机制,事务回滚策略等配置信息


(5)spring事务管理的一个FactoryBean
==>org.springframework.transaction.interceptor.TransactionProxyFactoryBean
==>内部初始化TransactionInterceptor,配置项:可以配置事务管理拦截器增强之外的别的拦截器,需要进行事务管理的的target, 进行事务管理的目标的接口proxyInterfaces
==>该类内部会调用afterPropertiesSet()方法,对目标target类生成一个代理对象。最终返回给业务使用。



【二】事务管理拦截器的执行过程TransactionInterceptor的invoke(final MethodInvocation invocation)方法
(1)获取要进行事务管理的业务类的class的类对象
(2)根据类对象class和要执行的方法的method对象,基于事务管理配置属性查询器获取事务机制的属性TransactionAttribute
(3)根据事务配置机制的属性获取事务管理的处理器PlatformTransactionManager
(4)根据类对象class和要执行的方法method对象获取事务管理,连接点标识joinpointIdentification(类的全路径+执行方法的名字)
(5)根据事务管理处理器PlatformTransactionManager,事务机制配置属性TransactionAttribute,事务连接点标识joinpointIdentification获取当前事务信息TransactionInfo
(6)继续执行下一个拦截器或目标业务管理bean的方法
(7)根据(6)的执行结果进行相应的事务操作
(8)如果(6)没有抛出异常,则先根据TransactionInfo进行相关资源的清理,然后根据TransactionInfo进行事务提交操作
(9)如果(6)抛出异常,则根据TransactionInfo进行事务回滚操作

 

【三】以xml配置方式进行事务管理的初始化原理解析
(1)    以下配置是事务管理机制属性配置

   <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="doReweight" propagation="REQUIRES_NEW"/>
            <tx:method name="doClear*" propagation="REQUIRES_NEW"/>
            <tx:method name="doSend*" propagation="REQUIRES_NEW"/>
            <tx:method name="doBatchSave*" propagation="REQUIRES_NEW"/>

            <!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->
            <tx:method name="get*" propagation="REQUIRED" read-only="true"/>
            <tx:method name="count*" propagation="REQUIRED" read-only="true"/>
            <tx:method name="find*" propagation="REQUIRED" read-only="true"/>
            <tx:method name="list*" propagation="REQUIRED" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <aop:config expose-proxy="true" proxy-target-class="true">
        <!-- 只对业务逻辑层实施事务 -->
        <aop:pointcut id="txPointcut" expression="execution(* com.mobile.thinks..service..*+.*(..))"/>
        <aop:advisor id="txAdvisor" advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>
View Code

(2)   在spring的IOC阶段是用org.springframework.transaction.config.TxNamespaceHandler进行解析该<tx:advice>配置,调用解析器org.springframework.transaction.config.TxAdviceBeanDefinitionParser
==>如果没有attributes的配置,则默认的配置属性查询器为org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
==>如果attributes的配置大于1个。报错
==>如果attributes的配置等于1个。
   >则解析 <tx:method>的配置。并为每一个method的配置形成一个org.springframework.transaction.interceptor.RuleBasedTransactionAttribute的对象。如果有回归策略则形成org.springframework.transaction.interceptor.RollbackRuleAttribute配置。将所有的method配置形成ManagedMap<TypedStringValue, RuleBasedTransactionAttribute> transactionAttributeMap集合
  >解析完method后,则想IOC注入事务属性配置查询器为org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource.将method解析后的transactionAttributeMap的集合赋值给其属性nameMap
==>想builder解析上下文注册了两个属性transactionAttributeSource(事务管理机制属性的查询器),transactionManager(事务管理的处理器)
==>解析tx的配置,最终形成的advisor是org.springframework.transaction.interceptor.TransactionInterceptor.其依赖了刚才解析的事务管理机制属性查询器transactionAttributeSource,和事务管理处理器transactionManager

(3)在spring的IOC阶段用的是org.springframework.aop.config.AopNamespaceHandler进行解析 <aop:config >该配置。调用的解析器为org.springframework.aop.config.ConfigBeanDefinitionParser

==>默认会向IOC容器中注册bean实力化的前后置处理器org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator(BeanPostProcessor接口实现类)
==>解析<aop:advisor>是向IOC容器中注册org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor.并建立txAdvice和txPointcut的依赖关系
==>解析<aop:pointcut>是向IOC容器中注册org.springframework.aop.aspectj.AspectJExpressionPointcut

 

=====================================================分割线========================================================

*****spring事务管理是基于对数据库链接的管理。以下所涉及的类,都是对数据库DataSource的直接管理,从而对数据库链接Connection的间接管理从而隐式进行数据库事务管理******

【一】org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
==>该类对DataSource进行动态代理,但返回的代理对象是Connection.具体的操作见TransactionAwareInvocationHandler的invoke方法。
==>在对数据库做任何操作的时候,都在invoke方法中。


【二】org.springframework.jdbc.datasource.TransactionAwareInvocationHandler
==>该类属性targetDataSource引用的是真正的DataSource实现。
==>该类属性target引用的是由 DataSourceUtils类通过targetDataSource获取的一个数据库链接,该链接与当前线程进行绑定。
==>在事务管理过程中Connection做的任何操作,都是代理对象进行操作的。都会调用该类的invoke方法,通过该方法对当前线程的事务管理进行绑定解绑等等操作。


【三】org.springframework.jdbc.datasource.DataSourceUtils
==>该类是从DataSource获取数据库链接,并结合Spring的TransactionSynchronizationManager类进行事务管理的相关操作
==>主要有获取Connection,释放Connection等相关操作。


【四】org.springframework.transaction.support.TransactionSynchronizationManager
==>对当前线程或当前事务的一些操作进行管理的操作类
==>可以在当前事务中注册一些事件执行。TransactionSynchronization接口的实现类

【五】org.springframework.transaction.support.TransactionSynchronization
==>该类定义一些事务处理过程中的一些事件处理回调方法。
==>例子:org.activiti.spring.TransactionSynchronizationAdapter
==>org.activiti.spring.SpringTransactionContext

 

(1)一个小案例,当事务提交后发布异步事件进行相应操作。如果事务未提交,回滚。则不发布该事件

public static void publishEvent(final ApplicationEvent event) {
        if (TransactionSynchronizationManager.isActualTransactionActive()) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                @Override
                public void afterCommit() {
                    applicationContext.publishEvent(event);
                    super.afterCommit();
                }
                
            });
        } else {
            applicationContext.publishEvent(event);
        }
    }
View Code

 (2)测试线程保管箱,用于说明TransactionSynchronizationManager属性中不同的线程保管箱的声明,是用于记录不同线程的事务管理的信息的存储。各个线程的事务信息是互不干扰和影响的。

import org.springframework.core.NamedThreadLocal;
/**
 * 代码测试结果:
 * 主线程的数值==>【我是主线程】
 * 非主线程的数值====>【我是副线程】
 * 10秒后被唤醒。。。。。。
 * 主线程第二次获取===>【我是主线程】
 * 
 * @author sxf
 *
 */
public class TestThreadLocal {
    
    
    public static void main(String[] args) {
        
        //在主线程声明一个ThreadLocal的线程保管箱,用于管理不同线程存储的不同的数值。看是否会线程间干扰
        final ThreadLocal<String> named=new NamedThreadLocal<String>("sxf test");
        
        //主线程设置数值
        named.set("【我是主线程】");
        //读取主线程存取的数值
        System.out.println("主线程的数值==>"+named.get());
        
        
        //启动一个新的线程,也使用主线程声明的线程保管箱
        Thread aThread=new Thread(){

            @Override
            public void run() {
                //副线程设置数值
                named.set("【我是副线程】");
                //读取副线程的存储的数值
                String falg=named.get();
                System.out.println("非主线程的数值====>"+falg);
            }
            
        };
        aThread.start();
        //主线程休眠10妙,待副线程执行完毕,再次从ThreadLocal里读取数值,看是否被副线程覆盖
        try {
            Thread.sleep(10000L);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("10秒后被唤醒。。。。。。");
        System.out.println("主线程第二次获取===>"+named.get());
        
        
    }

}
View Code

 

 

 

========================================xml方式配置事务管理,spring向IOC注册的核心关键类================================

(1)org.springframework.transaction.PlatformTransactionManager(事务管理的核心类)
==>该接口定义了三个方法,获取事务状态,提交事务,回滚事务
==>org.springframework.transaction.support.AbstractPlatformTransactionManager.该类对PlatformTransactionManager的三个方法进行重写,并写成模板方法。在再类内部定义各种方法,由子类实现。其中,commit(TransactionStatus status),rollback(TransactionStatus status)是final方法,不允许被重写。
==>jpa的事务管理的核心类:org.springframework.orm.jpa.JpaTransactionManager

(2)org.springframework.transaction.interceptor.TransactionAttributeSource(事务属性的接口,主要指事务的传播机制,是否只读事务,什么异常回滚等属性)
==>org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource(事务属性的一个实现类,是xml方式配置的方法表达式定义事务属性的核心实现类)
==>该类记录了,所切的业务方法的事务传播机制等属性配置信息。
==>该接口就定义了该方法,获取事务配置属性。TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass);

(3)org.springframework.transaction.interceptor.TransactionAttribute
===>事务配置属性
===>xml方式配置的事务属性,org.springframework.transaction.interceptor.RuleBasedTransactionAttribute(事务传播机制,是否只读的配置属性)
===>xml方式配置的事务属性,org.springframework.transaction.interceptor.RollbackRuleAttribute(事务回滚的配置属性)
===>xml方式配置的事务属性,org.springframework.transaction.interceptor.NoRollbackRuleAttribute(事务不回滚的配置属性)
===>tx的配置,会将配置的类加入到ManagedMap<TypedStringValue, RuleBasedTransactionAttribute> transactionAttributeMap

(4)xml方式配置的事务拦截器

<tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
                <tx:method name="required*" propagation="REQUIRED"/>
                <tx:method name="supports*" propagation="SUPPORTS"/>
                <tx:method name="mandatory*" propagation="MANDATORY"/>
                <tx:method name="requires_new*" propagation="REQUIRES_NEW"/>
                <tx:method name="not_supported*" propagation="NOT_SUPPORTED"/>
                <tx:method name="never*" propagation="NEVER"/>
                <tx:method name="nested*" propagation="NESTED"/>
                <tx:method name="*" propagation="REQUIRED"/>           
        </tx:attributes>
    </tx:advice>
View Code

===>org.springframework.transaction.interceptor.TransactionInterceptor
===>该类中存储了,事务配置的属性NameMatchTransactionAttributeSource,事务管理JpaTransactionManager

(5)xml方式配置的事务aop代理

<aop:config expose-proxy="true" proxy-target-class="true">
        <!-- 只对业务逻辑层实施事务 -->
        <aop:pointcut id="txPointcut" expression="execution(* com.sxf.test.service..*+.*(..))"/>
        <aop:advisor id="txAdvisor" advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
View Code

===>pointcut向IOC容器中注册:org.springframework.aop.aspectj.AspectJExpressionPointcut (匹配包名,决定对那些类进行事务管理,切面的定义)
===>AspectJExpressionPointcut类是org.springframework.aop.ClassFilter和org.springframework.aop.MethodMatcher和org.springframework.aop.Pointcut的实现类,用于判断当前类,是否要进行代理。

===>advisor向IOC容器中注册:org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor(这将来会在IOC申请Bean的时候,被编制到代理对象里的代理链条中,用于进行事务管理),该类有拦截器(增强,事务管理的拦截器机制)+切面(表达式决定那些类会被进行事务管理)

(6)spring进行事务管理的结构

==========================================Annotation方式进行spring事务管理=============================

    <!-- 注解方式配置事务管理机制 -->
    <!--  proxy-target-class="true" true使用cglib进行动态代理,false使用jdk -->
    <!--  expose-proxy="true" 暴露代理对象  -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"  expose-proxy="true"/>
View Code

(1)org.springframework.transaction.event.TransactionalEventListenerFactory
===>该类是org.springframework.context.event.EventListenerFactory
===>暂时不知道什么作用。

(2)org.springframework.transaction.config.internalTransactionalEventListenerFactory

(3)org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator
==>该类是org.springframework.beans.factory.config.BeanPostProcessor接口的实现类,会在IOC容器申请bean的时候,对bean进行加工,形成具有事务管理的代理对象,返回。


(4)org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
==>该类是事务管理配置属性的类的查找。
(5)org.springframework.transaction.interceptor.TransactionInterceptor
==>该类拥有事务管理的transcationManage和AnnotationTransactionAttributeSource

(6)org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor
===>该类拥有TransactionInterceptor和AnnotationTransactionAttributeSource


InfrastructureAdvisorAutoProxyCreator在申请bean的时候,会根据当前的class找到beanFactory里所有的advisor,然后从所有的Advisor中找到有资格作为该class的advisor,如果存在,则创建代理对象返回。Advisor里有PointCut来界定是否支持。



============================================spring框架的基础架构和实现策略=================================================
spring的IOC容器
(1)解析xml,将所有bean加载成BeanDefinition形式存储在DefaultListableBeanFactory中。
(2)控制依赖反转注入,向IOC容器中申请bean,创建bean,返回注入bean(递归形式进行链式注入,在创建的过程中对其进行前后加工bean,生成代理对象,或改变行为,注入属性)

spring的AOP代理
(1)会有一个创建代理对象的BeanPostProcessor接口实现对象,会在创建bean的前后进行处理bean,最终返回该bean一个代理对象。
(2)先在IOC容器中查找到所有的Advisor(增强+切面定义),然后在所有的Advisor中根据bean的class属性,进行匹配,看当前class是否需要增强。
(3)通过切面定义对class进行判定(Pointcut,ClassFilter,MethodMatcher),如果适合,收集起所有的Advisor,然后根据Order接口定义的优先级,进行排序。
(4)根据配置,生成代理对象,并返回代理对象,注入到要依赖的对象里。未来调用的时候进行增强逻辑的执行。

相关文章
|
7月前
|
存储 Java 文件存储
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— logback.xml 配置文件解析
本文解析了 `logback.xml` 配置文件的详细内容,包括日志输出格式、存储路径、控制台输出及日志级别等关键配置。通过定义 `LOG_PATTERN` 和 `FILE_PATH`,设置日志格式与存储路径;利用 `&lt;appender&gt;` 节点配置控制台和文件输出,支持日志滚动策略(如文件大小限制和保存时长);最后通过 `&lt;logger&gt;` 和 `&lt;root&gt;` 定义日志级别与输出方式。此配置适用于精细化管理日志输出,满足不同场景需求。
1676 1
|
7月前
|
监控 Java 应用服务中间件
微服务——SpringBoot使用归纳——为什么学习Spring Boot
本文主要探讨为什么学习Spring Boot。从Spring官方定位来看,Spring Boot旨在快速启动和运行项目,简化配置与编码。其优点包括:1) 良好的基因,继承了Spring框架的优点;2) 简化编码,通过starter依赖减少手动配置;3) 简化配置,采用Java Config方式替代繁琐的XML配置;4) 简化部署,内嵌Tomcat支持一键式启动;5) 简化监控,提供运行期性能参数获取功能。此外,从未来发展趋势看,微服务架构逐渐成为主流,而Spring Boot作为官方推荐技术,与Spring Cloud配合使用,将成为未来发展的重要方向。
213 0
微服务——SpringBoot使用归纳——为什么学习Spring Boot
|
2月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
6月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
402 70
|
6月前
|
Java Spring
Spring框架的学习与应用
总的来说,Spring框架是Java开发中的一把强大的工具。通过理解其核心概念,通过实践来学习和掌握,你可以充分利用Spring框架的强大功能,提高你的开发效率和代码质量。
150 20
|
6月前
|
Java 关系型数据库 MySQL
深入解析 @Transactional——Spring 事务管理的核心
本文深入解析了 Spring Boot 中 `@Transactional` 的工作机制、常见陷阱及最佳实践。作为事务管理的核心注解,`@Transactional` 确保数据库操作的原子性,避免数据不一致问题。文章通过示例讲解了其基本用法、默认回滚规则(仅未捕获的运行时异常触发回滚)、因 `try-catch` 或方法访问修饰符不当导致失效的情况,以及数据库引擎对事务的支持要求。最后总结了使用 `@Transactional` 的五大最佳实践,帮助开发者规避常见问题,提升项目稳定性与可靠性。
872 12
|
8月前
|
传感器 监控 安全
智慧工地云平台的技术架构解析:微服务+Spring Cloud如何支撑海量数据?
慧工地解决方案依托AI、物联网和BIM技术,实现对施工现场的全方位、立体化管理。通过规范施工、减少安全隐患、节省人力、降低运营成本,提升工地管理的安全性、效率和精益度。该方案适用于大型建筑、基础设施、房地产开发等场景,具备微服务架构、大数据与AI分析、物联网设备联网、多端协同等创新点,推动建筑行业向数字化、智能化转型。未来将融合5G、区块链等技术,助力智慧城市建设。
365 1
|
7月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
131 0
|
7月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
665 29

推荐镜像

更多
  • DNS