spring事务详解(三)源码详解 |
您所在的位置:网站首页 › spring事务代码实现 › spring事务详解(三)源码详解 |
系列目录
spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一、引子在Spring中,事务有两种实现方式: 编程式事务管理: 编程式事务管理使用TransactionTemplate可实现更细粒度的事务控制。 申明式事务管理: 基于Spring AOP实现。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。申明式事务管理不需要入侵代码,通过@Transactional就可以进行事务操作,更快捷而且简单(尤其是配合spring boot自动配置,可以说是精简至极!),且大部分业务都可以满足,推荐使用。 其实不管是编程式事务还是申明式事务,最终调用的底层核心代码是一致的。本章分别从编程式、申明式入手,再进入核心源码贯穿式讲解。 二、事务源码 2.1 编程式事务TransactionTemplate编程式事务,Spring已经给我们提供好了模板类TransactionTemplate,可以很方便的使用,如下图: TransactionTemplate全路径名是:org.springframework.transaction.support.TransactionTemplate。看包名也知道了这是spring对事务的模板类。(spring动不动就是各种Template...),看下类图先: 一看,哟西,实现了TransactionOperations、InitializingBean这2个接口(熟悉spring源码的知道这个InitializingBean又是老套路),我们来看下接口源码如下: 1 public interface TransactionOperations { 2 3 /** 4 * Execute the action specified by the given callback object within a transaction. 5 *Allows for returning a result object created within the transaction, that is, 6 * a domain object or a collection of domain objects. A RuntimeException thrown 7 * by the callback is treated as a fatal exception that enforces a rollback. 8 * Such an exception gets propagated to the caller of the template. 9 * @param action the callback object that specifies the transactional action 10 * @return a result object returned by the callback, or {@code null} if none 11 * @throws TransactionException in case of initialization, rollback, or system errors 12 * @throws RuntimeException if thrown by the TransactionCallback 13 */ 14 T execute(TransactionCallback action) throws TransactionException; 15 16 } 17 18 public interface InitializingBean { 19 20 /** 21 * Invoked by a BeanFactory after it has set all bean properties supplied 22 * (and satisfied BeanFactoryAware and ApplicationContextAware). 23 * This method allows the bean instance to perform initialization only 24 * possible when all bean properties have been set and to throw an 25 * exception in the event of misconfiguration. 26 * @throws Exception in the event of misconfiguration (such 27 * as failure to set an essential property) or if initialization fails. 28 */ 29 void afterPropertiesSet() throws Exception; 30 31 } 如上图,TransactionOperations这个接口用来执行事务的回调方法,InitializingBean这个是典型的spring bean初始化流程中(飞机票:Spring IOC(四)总结升华篇)的预留接口,专用用来在bean属性加载完毕时执行的方法。 回到正题,TransactionTemplate的2个接口的impl方法做了什么? 1 @Override 2 public void afterPropertiesSet() { 3 if (this.transactionManager == null) { 4 throw new IllegalArgumentException("Property 'transactionManager' is required"); 5 } 6 } 7 8 9 @Override 10 public T execute(TransactionCallback action) throws TransactionException { // 内部封装好的事务管理器 11 if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) { 12 return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action); 13 }// 需要手动获取事务,执行方法,提交事务的管理器 14 else {// 1.获取事务状态 15 TransactionStatus status = this.transactionManager.getTransaction(this); 16 T result; 17 try {// 2.执行业务逻辑 18 result = action.doInTransaction(status); 19 } 20 catch (RuntimeException ex) { 21 // 应用运行时异常 -> 回滚 22 rollbackOnException(status, ex); 23 throw ex; 24 } 25 catch (Error err) { 26 // Error异常 -> 回滚 27 rollbackOnException(status, err); 28 throw err; 29 } 30 catch (Throwable ex) { 31 // 未知异常 -> 回滚 32 rollbackOnException(status, ex); 33 throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception"); 34 }// 3.事务提交 35 this.transactionManager.commit(status); 36 return result; 37 } 38 }如上图所示,实际上afterPropertiesSet只是校验了事务管理器不为空,execute()才是核心方法,execute主要步骤: 1.getTransaction()获取事务,源码见3.3.1 2.doInTransaction()执行业务逻辑,这里就是用户自定义的业务代码。如果是没有返回值的,就是doInTransactionWithoutResult()。 3.commit()事务提交:调用AbstractPlatformTransactionManager的commit,rollbackOnException()异常回滚:调用AbstractPlatformTransactionManager的rollback(),事务提交回滚,源码见3.3.3 2.2 申明式事务@Transactional 1.AOP相关概念 申明式事务使用的是spring AOP,即面向切面编程。(什么❓你不知道什么是AOP...一句话概括就是:把业务代码中重复代码做成一个切面,提取出来,并定义哪些方法需要执行这个切面。其它的自行百度吧...)AOP核心概念如下: 通知(Advice):定义了切面(各处业务代码中都需要的逻辑提炼成的一个切面)做什么what+when何时使用。例如:前置通知Before、后置通知After、返回通知After-returning、异常通知After-throwing、环绕通知Around. 连接点(Joint point):程序执行过程中能够插入切面的点,一般有多个。比如调用方式时、抛出异常时。 切点(Pointcut):切点定义了连接点,切点包含多个连接点,即where哪里使用通知.通常指定类+方法 或者 正则表达式来匹配 类和方法名称。 切面(Aspect):切面=通知+切点,即when+where+what何时何地做什么。 引入(Introduction):允许我们向现有的类添加新方法或属性。 织入(Weaving):织入是把切面应用到目标对象并创建新的代理对象的过程。 2.申明式事务申明式事务整体调用过程,可以抽出2条线: 1.使用代理模式,生成代理增强类。 2.根据代理事务管理配置类,配置事务的织入,在业务方法前后进行环绕增强,增加一些事务的相关操作。例如获取事务属性、提交事务、回滚事务。 过程如下图: 申明式事务使用@Transactional这种注解的方式,那么我们就从springboot 容器启动时的自动配置载入(spring boot容器启动详解)开始看。在/META-INF/spring.factories中配置文件中查找,如下图: 载入2个关于事务的自动配置类: org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration, jta咱们就不看了,看一下TransactionAutoConfiguration这个自动配置类: 1 @Configuration 2 @ConditionalOnClass(PlatformTransactionManager.class) 3 @AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class, 4 DataSourceTransactionManagerAutoConfiguration.class, 5 Neo4jDataAutoConfiguration.class }) 6 @EnableConfigurationProperties(TransactionProperties.class) 7 public class TransactionAutoConfiguration { 8 9 @Bean 10 @ConditionalOnMissingBean 11 public TransactionManagerCustomizers platformTransactionManagerCustomizers( 12 ObjectProvider |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |