目录

  • 一、介绍
  • 二、TransactionInterceptor 分析
    • 2. 流程
    • 2.1 invoke
      • 2.1.1 TransactionAspectSupport#invokeWithinTransaction
    • 2.2 getTransactionAttribute
    • 2.3 computeTransactionAttribute
    • 2.4 TransactionAspectSupport#determineTransactionManager
    • 2.5 TransactionAspectSupport#createTransactionIfNecessary
    • 2.6 AbstractPlatformTransactionManager#getTransaction
    • 2.7 DataSourceTransactionManager#doGetTransaction
    • 2.7 AbstractPlatformTransactionManager#suspend
    • 2.8 AbstractPlatformTransactionManager#startTransaction
    • 2.9 DataSourceTransactionManager#doBegin
    • 2.10 TransactionAspectSupport#prepareTransactionInfo
  • 三、小结

一、介绍

Spring 事务分为两种,声明式和编程式, 声明式就是 在 方法或者接口上加 @Transactional的注解, 这样就可以交给Spring 管理它的提交,回滚,等等, 编程式就是用spring提供的模板 ,通过回调方法实现. 不管使用哪一种,最后事务的执行入口都是TransactionInterceptor的invoke方法,这个在上一章Spring源码解析之-- 事务注解 处理流程 分析中有介绍的. 下面就从这个入口,开始分析如何开启事务

二、TransactionInterceptor 分析

2. 流程

如下图,首先看一下事务的大致流程如下:

接下来再分析源码

2.1 invoke

invoke 方法就是一个入口, 主要就t是先获取对应的 targetClass, 然后适配类 TransactionAspectSupport 的invokeWithinTransaction 方法

 public Object invoke(MethodInvocation invocation) throws Throwable {// Work out the target class: may be {@code null}.// The TransactionAttributeSource should be passed the target class// as well as the method, which may be from an interface./**首先这里是需要获取 targetClass, 如果是代理类(如 CglibProxy或者 jdkProyx),那就 获取对应的 target class**/Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);/**适配 类 TransactionAspectSupport 的invokeWithinTransaction 方法这里是传入了一个回调函数,也就是具体的处理逻辑**/return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);}

2.1.1 TransactionAspectSupport#invokeWithinTransaction

invokeWithinTransaction 这里主要做了以下几件事情:

  1. 获取事务的属性
  2. 加载配置中配的transactionManager
  3. 不同的事务处理方式使用不同的事务
  4. 在目标方法执行前获取事务并收集事务信息
  5. 执行目标方法
  6. 一旦出现异常,尝试异常处理,不是所有的异常都回滚, Spring 只对RuntimeException 处理
  7. 提交事务前的事务信息清除
  8. 提交事务
  protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,final InvocationCallback invocation) throws Throwable {// 获取事务属性,如果 transaction attribute 为null, 那这个方法就是 非事务类型TransactionAttributeSource tas = getTransactionAttributeSource();final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);// 根据事务属性确定对应的事务final TransactionManager tm = determineTransactionManager(txAttr);// 这里是反应式事务,暂时不分析if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {throw new TransactionUsageException("Unsupported annotated transaction on suspending function detected: " + method +". Use TransactionalOperator.transactional extensions instead.");}ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());if (adapter == null) {throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +method.getReturnType());}return new ReactiveTransactionSupport(adapter);});return txSupport.invokeWithinTransaction(method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);}PlatformTransactionManager ptm = asPlatformTransactionManager(tm);// 获取方法唯一标识,这里的 descriptor 就是在 获取 事务属性txAttr时 设置进去的.final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);/**这里是 申明式事务我们一般申明式 事务定义的是DataSourceTransactionManager就不是CallbackPreferringPlatformTransactionManager,CallbackPreferringPlatformTransactionManager 是通过回调方法实现事务的**/if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {// 创建 TransactionInfo TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);Object retVal;try {// This is an around advice: Invoke the next interceptor in the chain.// This will normally result in a target object being invoked.// 执行被争强方法retVal = invocation.proceedWithInvocation();}catch (Throwable ex) {// target invocation exception// 异常回滚completeTransactionAfterThrowing(txInfo, ex);throw ex;}finally {// 清除信息cleanupTransactionInfo(txInfo);}if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {// Set rollback-only in case of Vavr failure matching our rollback rules...TransactionStatus status = txInfo.getTransactionStatus();if (status != null && txAttr != null) {retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);}}// 提交commitTransactionAfterReturning(txInfo);return retVal;}// 编程式事务else {Object result;final ThrowableHolder throwableHolder = new ThrowableHolder();// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.try {result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);try {Object retVal = invocation.proceedWithInvocation();if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {// Set rollback-only in case of Vavr failure matching our rollback rules...retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);}return retVal;}catch (Throwable ex) {if (txAttr.rollbackOn(ex)) {// A RuntimeException: will lead to a rollback.if (ex instanceof RuntimeException) {throw (RuntimeException) ex;}else {throw new ThrowableHolderException(ex);}}else {// A normal return value: will lead to a commit.throwableHolder.throwable = ex;return null;}}finally {cleanupTransactionInfo(txInfo);}});}catch (ThrowableHolderException ex) {throw ex.getCause();}catch (TransactionSystemException ex2) {if (throwableHolder.throwable != null) {logger.error("Application exception overridden by commit exception", throwableHolder.throwable);ex2.initApplicationException(throwableHolder.throwable);}throw ex2;}catch (Throwable ex2) {if (throwableHolder.throwable != null) {logger.error("Application exception overridden by commit exception", throwableHolder.throwable);}throw ex2;}// Check result state: It might indicate a Throwable to rethrow.if (throwableHolder.throwable != null) {throw throwableHolder.throwable;}return result;}}

2.2 getTransactionAttribute

getTransactionAttribute 方法比较简单,就是获取事务属性并缓存, 如果事务存在,那就对事务 加一个属性描述,对应的值为 类名.方法名

public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {// 如果是Object.class 类,直接返回if (method.getDeclaringClass() == Object.class) {return null;}/** 首先 去查看是否有缓存,getCacheKey 里面 就是一个单纯的 new 了一个对象 MethodClassKey,MethodClassKey重写了toString() 方法, 主要就是 用了 method+targetClass**/Object cacheKey = getCacheKey(method, targetClass);TransactionAttribute cached = this.attributeCache.get(cacheKey);// 如果不为null, 要么就是具体的事务属性,要么就是 默认的空属性, 如果是默认的空事务属性,那就 返回nullif (cached != null) {if (cached == NULL_TRANSACTION_ATTRIBUTE) {return null;}else {return cached;}}else {// 如果是空 ,那就再次获取一遍TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);// 放入缓存, 如果 属性为null, 设置 对应的value 为NULL_TRANSACTION_ATTRIBUTEif (txAttr == null) {this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);}else {// 放入属性之前, 对 事务属性 设置一个 描述,就是用 类名.方法名String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);if (txAttr instanceof DefaultTransactionAttribute) {((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);}if (logger.isTraceEnabled()) {logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);}this.attributeCache.put(cacheKey, txAttr);}return txAttr;}}

2.3 computeTransactionAttribute

computeTransactionAttribute 方法主要是 寻找事务属性的, 主要流程如下:

  1. 首先判断 方法 是 什么类型的,如果不是 public 类型的,直接返回null
  2. 接下来获取 事务属性,这里是按照 targetClass.Method ->tragetClass ->interface.Method -> interface 的顺序获取属性的, 也就是说,如果 你 接口上有事务属性, 但是如果你目标类的 方法上还有属性,那就以 目标类的方法的属性为准
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {/** 这里要求 事务的方法是 public的,不然不生效注解式事务里面 AnnotationTransactionAttributeSource 里面默认是 true 的**/if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {return null;}/**这里的方法可能是在一个接口上,所以这里是获取target class 的具体方法比如: method 为IFoo.bar() , targetClass 是 DefaultFoo ,这里是需要获取 DefaultFoo.bar()方法同时这里还处理了可能出现桥接的问题如果 targetClass 为null ,那方法就不会变**/Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);/**第一次尝试: 先对 方法上 @Transactional 进行解析解析 方法上的@Transactional属性,利用 springTransactionAnnotationParser 对 方法上的@Transactional 进行解析里面的属性, 返回 TransactionAttribute **/TransactionAttribute txAttr = findTransactionAttribute(specificMethod);if (txAttr != null) {return txAttr;}/**第二次: 如果上一步没有获取到,那就可能在 target class上面对 target class 进行解析, 如果找到对应的事务属性, 并且是 用户级别的方法,那就返回**/txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {return txAttr;}/**第三步 如果 在目标类上的 方法和类上都没有找到 对应的 事务属性那就去 原始的接口上去寻找, 还是 先从 method 上面开始,如果没有,那就看接口上有没有 配置事务属性**/if (specificMethod != method) {// Fallback is to look at the original method.txAttr = findTransactionAttribute(method);if (txAttr != null) {return txAttr;}// Last fallback is the class of the original method.txAttr = findTransactionAttribute(method.getDeclaringClass());if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {return txAttr;}}// 最后都没有找到,那就返回nullreturn null;}

2.4 TransactionAspectSupport#determineTransactionManager

determineTransactionManager 方法的逻辑也比较简单:

  1. 判断是否有事务属性,如果没有直接返回
  2. 根据事务的名字,获取对应的事务管理器
  3. 如果事务没有设置名字, 获取默认的事务管理器
protected TransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {// 如果 事务属性 txAttr 为null, 那就直接返回if (txAttr == null || this.beanFactory == null) {return getTransactionManager();}// 获取对应的事务注解上的名字String qualifier = txAttr.getQualifier();if (StringUtils.hasText(qualifier)) {// 根据指定的事务注解name去查询return determineQualifiedTransactionManager(this.beanFactory, qualifier);}//根据默认的事务注解name查询else if (StringUtils.hasText(this.transactionManagerBeanName)) {return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);}else {// 获取默认的 事务管理器TransactionManager defaultTransactionManager = getTransactionManager();if (defaultTransactionManager == null) {defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);if (defaultTransactionManager == null) {defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);this.transactionManagerCache.putIfAbsent(DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);}}return defaultTransactionManager;}}/**这里从(cache->beanFactory)里面获取 指定名字的事务管理器**/private TransactionManager determineQualifiedTransactionManager(BeanFactory beanFactory, String qualifier) {// 这里首先也是先从缓存里面获取TransactionManager txManager = this.transactionManagerCache.get(qualifier);//如果缓存不存在,那就从BeanFactory 里面获取,然后再放进缓存if (txManager == null) {txManager = BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, TransactionManager.class, qualifier);this.transactionManagerCache.putIfAbsent(qualifier, txManager);}return txManager;}

2.5 TransactionAspectSupport#createTransactionIfNecessary

createTransactionIfNecessary 这个方法主要是判断是否有必要创建事务 ,

 protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {/**如果没有指定名称,则将方法标识应用为事务名称,就是之前设置的 class.method**/if (txAttr != null && txAttr.getName() == null) {txAttr = new DelegatingTransactionAttribute(txAttr) {@Overridepublic String getName() {return joinpointIdentification;}};}TransactionStatus status = null;if (txAttr != null) {if (tm != null) {status = tm.getTransaction(txAttr);}else {if (logger.isDebugEnabled()) {logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +"] because no transaction manager has been configured");}}}return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);}

2.6 AbstractPlatformTransactionManager#getTransaction

getTransaction方法 比较核心了, 主要做了以下几件事:
1.获取事务
2. 如果当前线程存在事务,则转向嵌套事务处理
3. 事务的超时设置验证
4. 事务的传播属性验证
5. 隔离级别, timeout ,connectinHolder 等配置
6. 绑定到当前线程

public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)throws TransactionException {// 如果传入的definition 为null , 就从新定义一个新的definition (StaticTransactionDefinition 类型)TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());//这里时获取 当前线程缓存在 threadlocal里面的 connection, 如果没有connection,那DataSourceTransactionObject 里面的//connectionHolder 为nullObject transaction = doGetTransaction();boolean debugEnabled = logger.isDebugEnabled();// 这里时判断如果上面的 connectionHolder 不为空,并且是有效的if (isExistingTransaction(transaction)) {// Existing transaction found -> check propagation behavior to find out how to behave.// 这里是 为已经存在的 transaction创建一个 TransactionStatus对象return handleExistingTransaction(def, transaction, debugEnabled);}// Check definition settings for new transaction.if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());}//如果事务定义为MANDATORY,那就是必须在一个已有事务里面运行, 这里没有事务就会报错if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");}else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {// 这块空挂起,不做任何操作SuspendedResourcesHolder suspendedResources = suspend(null);if (debugEnabled) {logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);}try {// 这里就是开启事务return startTransaction(def, transaction, debugEnabled, suspendedResources);}catch (RuntimeException | Error ex) {resume(null, suspendedResources);throw ex;}}else {// Create "empty" transaction: no actual transaction, but potentially synchronization.if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {logger.warn("Custom isolation level specified but no actual transaction initiated; " +"isolation level will effectively be ignored: " + def);}boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);}}

2.7 DataSourceTransactionManager#doGetTransaction

doGetTransaction 方法主要就是为了获取当前线程的 connection, 通过查看缓存在 TransactionSynchronizationManager.class里面的resources 的threadLocal 里面的connection,如果没有就为null
后面doBegin 方法里面最好是绑定数据源,就是存放在一个 ThreadLocal里面, 里面存放的是Map,key 就是 datasource,Value 就是对应的connection

 protected Object doGetTransaction() {// 创建一个 DataSourceTransactionObject 对象DataSourceTransactionObject txObject = new DataSourceTransactionObject();// 设置 此事务中是否允许保存点, isNestedTransactionAllowed() 为true,是在事务创建时设置的txObject.setSavepointAllowed(isNestedTransactionAllowed());/**获取当前线程的connection 缓存,如果不存在,那就为null这里是一个Map 存储的, key 是datasource ,value 是connection**/ConnectionHolder conHolder =(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());txObject.setConnectionHolder(conHolder, false);return txObject;}

2.7 AbstractPlatformTransactionManager#suspend

suspend 方法主要是对事务进行挂起,对于挂起操作主要的目的是记录原有事务的状态,以便后续操作对原有事务的恢复.

protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {// 如果当前线程的事务同步器是否是活跃状态if (TransactionSynchronizationManager.isSynchronizationActive()) {/** 这里获取所有事务同步器的 快照,先悬挂住,并把当前线程清空,最后返回一个 new SuspendedResourcesHolder  对象**/List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();try {Object suspendedResources = null;if (transaction != null) {suspendedResources = doSuspend(transaction);}String name = TransactionSynchronizationManager.getCurrentTransactionName();TransactionSynchronizationManager.setCurrentTransactionName(null);boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();TransactionSynchronizationManager.setActualTransactionActive(false);return new SuspendedResourcesHolder(suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);}catch (RuntimeException | Error ex) {// doSuspend failed - original transaction is still active...doResumeSynchronization(suspendedSynchronizations);throw ex;}}else if (transaction != null) {// Transaction active but no synchronization active.Object suspendedResources = doSuspend(transaction);return new SuspendedResourcesHolder(suspendedResources);}else {// Neither transaction nor synchronization active.return null;}}

2.8 AbstractPlatformTransactionManager#startTransaction

startTransaction方法 主要就是 开启新事务 ,详细逻辑在下面的doBegin

 private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);DefaultTransactionStatus status = newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);// 这里主要是构造transaction, 包括设置ConnectionHolder ,隔离级别,timeout ,如果是新连接,绑定到当前线程doBegin(transaction, definition);// 新同步事务的设置prepareSynchronization(status, definition);return status;}

2.9 DataSourceTransactionManager#doBegin

doBegin 主要是构造transaction, 包括设置ConnectionHolder ,隔离级别,timeout ,这类不是spring 完成,而是交给底层的数据连接去做的,如果是新连接,绑定到当前线程

protected void doBegin(Object transaction, TransactionDefinition definition) {// 转换为 DataSourceTransactionObjectDataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;Connection con = null;try {// 如果没有数据连接connectionif (!txObject.hasConnectionHolder() ||txObject.getConnectionHolder().isSynchronizedWithTransaction()) {// 这里就是调用数据源进行获取 connection 并进行绑定Connection newCon = obtainDataSource().getConnection();if (logger.isDebugEnabled()) {logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");}txObject.setConnectionHolder(new ConnectionHolder(newCon), true);}txObject.getConnectionHolder().setSynchronizedWithTransaction(true);con = txObject.getConnectionHolder().getConnection();// 对connection 设置 隔离级别和 是否只读属性Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);txObject.setPreviousIsolationLevel(previousIsolationLevel);txObject.setReadOnly(definition.isReadOnly());// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,// so we don't want to do it unnecessarily (for example if we've explicitly// configured the connection pool to set it already)./**这里就是关闭自动提交, 就是开启事务了,由Spring 控制提交**/if (con.getAutoCommit()) {txObject.setMustRestoreAutoCommit(true);if (logger.isDebugEnabled()) {logger.debug("Switching JDBC Connection [" + con + "] to manual commit");}con.setAutoCommit(false);}/**设置只读事务,就是这事务内没有新增,修改,删除操作只有查询操作,不需要数据库锁等操作,减少数据库压力,还有就是其他事务提交的数据,在"SET TRANSACTION READ ONLY" 是看不到的**/prepareTransactionalConnection(con, definition);// 配置 判断当前线程是否有事务的 标志txObject.getConnectionHolder().setTransactionActive(true);// 设置timeoutint timeout = determineTimeout(definition);if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {txObject.getConnectionHolder().setTimeoutInSeconds(timeout);}// Bind the connection holder to the thread.// 绑定这connection 到当前线程if (txObject.isNewConnectionHolder()) {TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());}}catch (Throwable ex) {if (txObject.isNewConnectionHolder()) {DataSourceUtils.releaseConnection(con, obtainDataSource());txObject.setConnectionHolder(null, false);}throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);}}

2.10 TransactionAspectSupport#prepareTransactionInfo

当已经建立事务连接并完成了事务的提取后,我们需要将所有的事务信息统一记录在TransactionInfo 类型的实例里面,这个实例包含了目标方法开始前的所有状态信息,一旦事务执行失败,Spring 会通过TransactionInfo 类型的实例中的信息来进行回滚等后续工作.
方法prepareTransactionInfo 主要做了以下几件事:

  1. 创建了一个TransactionInfo 实例, 把tm,txAttr,joinpointIdentification,status 属性都填充进去了
  2. 先把之前的老的TransactionInfo 保存起来, 并把当前的TransactionInfo 放到ThreadLocal 里面暴露出去 ,这样就便于后续的
    还原,提交,回滚等一系列操作.
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,@Nullable TransactionAttribute txAttr, String joinpointIdentification,@Nullable TransactionStatus status) {TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);if (txAttr != null) {// We need a transaction for this method...if (logger.isTraceEnabled()) {logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");}// The transaction manager will flag an error if an incompatible tx already exists.txInfo.newTransactionStatus(status);}else {// The TransactionInfo.hasTransaction() method will return false. We created it only// to preserve the integrity of the ThreadLocal stack maintained in this class.if (logger.isTraceEnabled()) {logger.trace("No need to create transaction for [" + joinpointIdentification +"]: This method is not transactional.");}}// We always bind the TransactionInfo to the thread, even if we didn't create// a new transaction here. This guarantees that the TransactionInfo stack// will be managed correctly even if no transaction was created by this aspect.txInfo.bindToThread();return txInfo;}

三、小结

本章主要介绍了 创建事务相关的源码解析, 下一章介绍 事务的提交、回滚、异常处理等.

支付宝 微信
如果有帮助记得打赏哦 特别需要您的打赏哦

Spring源码解析之-- 事务TransactionInterceptor 分析(开启事务)相关推荐

  1. Spring源码解析 - AbstractBeanFactory 实现接口与父类分析

    2019独角兽企业重金招聘Python工程师标准>>> 我们先来看类图吧: 除了BeanFactory这一支的接口,AbstractBeanFactory主要实现了AliasRegi ...

  2. Spring源码解析【完整版】--【bilibili地址:https://www.bilibili.com/video/BV1oW41167AV】

    [本文为bilibili视频雷丰阳的Spring源码解析的完整版总结文章,其中文章前面大部分为他人博文的搬运,后面补充了其未总结的部分] 一.Java的注解 1. 注解的概念 注释:用文字描述程序,给 ...

  3. Spring源码解析:自定义标签的解析过程

    2019独角兽企业重金招聘Python工程师标准>>> spring version : 4.3.x Spring 中的标签分为默认标签和自定义标签两类,上一篇我们探究了默认标签的解 ...

  4. Spring 源码解析 -- SpringWeb过滤器Filter解析

    简介 在上几篇文章中探索了请求处理相关的代码,本篇开始探索请求处理前的一些操作代码,如Filter.本篇探索Filter初始化.请求处理等相关代码. 前言 说先简单的定义相关的测试代码: 启动类: i ...

  5. Spring源码解析 -- SpringWeb请求参数获取解析

    Spring源码解析 – SpringWeb请求参数获取解析 简介 在文章:Spring Web 请求初探中,我们看到最后方法反射调用的相关代码,本篇文章就探索其中的参数是如何从请求中获取的 概览 方 ...

  6. Spring源码解析 -- SpringWeb请求映射Map初始化

    简介 在上篇文章中,大致解析了Spring如何将请求路径与处理方法进行映射,但映射相关的初始化对于我们来说还是一团迷雾 本篇文章就来探索下,请求路径和处理方法的映射,是如何进行初始化的 概览 基于上篇 ...

  7. Spring源码解析-bean实例化

    Spring源码解析-bean实例化 ​ 本文介绍Spring创建 bean 过程中的第一个步骤:实例化 bean. 1. Bean实例化源码 ​ 虽然实例化Bean有多种方式(包括静态工厂和工厂实例 ...

  8. 人人都能看懂的Spring源码解析,Spring如何解决循环依赖

    人人都能看懂的Spring源码解析,Spring如何解决循环依赖 原理解析 什么是循环依赖 循环依赖会有什么问题? 如何解决循环依赖 问题的根本原因 如何解决 为什么需要三级缓存? Spring的三级 ...

  9. Spring 源码解析 - Bean创建过程 以及 解决循环依赖

    一.Spring Bean创建过程以及循环依赖 上篇文章对 Spring Bean资源的加载注册过程进行了源码梳理和解析,我们可以得到结论,资源文件中的 bean 定义信息,被组装成了 BeanDef ...

最新文章

  1. 旷视唐文斌:你到底给谁创造了什么样的价值?这是AI产品的灵魂拷问丨MEET2020...
  2. 主模式和野蛮模式_网络野蛮行为的含混性和观念
  3. php如何抓取网页内容,php如何抓取网页数据?
  4. 解决GetManifestResourceNames()无法读取资源文件
  5. php静态文件怎么生成器,[新姿势]我用过的静态站点生成器们
  6. Java成员方法的声明和调用
  7. jq移除一条html语句,jquery html()删除脚本标签
  8. 提高C#编程水平的50个要诀
  9. 微信文件夹下不可言说的秘密自动生成小视频文件
  10. 经纬度 度分秒转换为小数
  11. icem网格数和节点数_ansys中划分网格后,如何查看单元数和节点数
  12. JS 微信公众号如何跳转到另一个微信公众号的链接
  13. 【渗透测试笔记】之【Cobalt Strike小技巧——后台挂起CS服务端】
  14. 三星android强制关机,三星怎么强制关机
  15. c语言如何计算中位数,如何计算中位数?
  16. 做一个迷你播放器放在桌面
  17. SpringBoot2.0Web开发实例(一)WebJars静态资源
  18. vijosP1285 佳佳的魔法药水
  19. JCD 驱动 - 复杂系统设计应对之道
  20. 回溯法解决n皇后问题

热门文章

  1. EWM和ERP的QM集成实现先判检再收货
  2. FontForge不识别,WINDOWS报错:mstmc.ttf真的是字体文件吗?
  3. win10出现win10系统即将过期,请激活的处理办法
  4. vue js数字转换成汉字展示
  5. mysql事务能支持多大_MySQL事务调优
  6. yolov3 使用darknet的python接口处理单张图片和视频和摄像头视频流
  7. GBJ3510-ASEMI电磁炉专用整流桥GBJ3510
  8. ZIP压缩包的自动设置密码可以这样解除
  9. 人工智能在《LOL王者荣耀》游戏中的角色
  10. tcpdump中的Flags S 和Flags 是什么意思 ------顺便看看三次握手包