第23讲:Spring事务底层实现

代码块1:invoke

 TransactionInterceptor.class
    @Override
	@Nullable
	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.
              //获取目标类 见 内部代码块1
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
          //见 内部代码块2
		return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
	} 
 
  内部代码块1:AopUtils.getTargetClass(invocation.getThis()) 
  AopUtils.class
  /**
	 * Determine the target class of the given bean instance which might be an AOP proxy.
	 * <p>Returns the target class for an AOP proxy or the plain class otherwise.
	 * @param candidate the instance to check (might be an AOP proxy)
	 * @return the target class (or the plain class of the given object as fallback;
	 * never {@code null})
	 * @see org.springframework.aop.TargetClassAware#getTargetClass()
	 * @see org.springframework.aop.framework.AopProxyUtils#ultimateTargetClass(Object)
	 */
  //如果是代理类,就返回代理类的目标类。否则,如果是普通类就返回该类本身
	public static Class<?> getTargetClass(Object candidate) {
		Assert.notNull(candidate, "Candidate object must not be null");
		Class<?> result = null;
		if (candidate instanceof TargetClassAware) {
			result = ((TargetClassAware) candidate).getTargetClass();
		}
		if (result == null) {
                      //如果是cglib则返回目标对象的父类,否则为jdk的动态代理,直接返回目标对象
			result = (isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass());
		}
		return result;
	}
 
   内部代码块2:
   TransactionAspectSupport.class 
   /**
	 * General delegate for around-advice-based subclasses, delegating to several other template
	 * methods on this class. Able to handle {@link CallbackPreferringPlatformTransactionManager}
	 * as well as regular {@link PlatformTransactionManager} implementations.
	 * @param method the Method being invoked
	 * @param targetClass the target class that we're invoking the method on
	 * @param invocation the callback to use for proceeding with the target invocation
	 * @return the return value of the method, if any
	 * @throws Throwable propagated from the target invocation
	 */
	@Nullable
	protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
          //如果某个方法的事务属性为空,则这个方法是非事务的
          
          //获取事务属性 见,内部代码块3:getTransactionAttributeSource
		TransactionAttributeSource tas = getTransactionAttributeSource();
          //获取与目标方法对应的TransactionAttribute (事件属性),见 内部代码块7 tas.getTransactionAttribute(method, targetClass)
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
          //获取事务管理器(用于做事务的提交、回滚等操作的)
          //见 内部代码块8:determineTransactionManager
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
          //获取方法名字,做日志用的不重要
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
            //一般会执行if里面的语句
		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls. 
                   //该对象能获取事务、提交事务、回滚事务
                   //这个方法内部会开启事务
                   // 见 内部代码块9:createTransactionIfNecessary
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
                   //下面的代码就是执行具体的我们所编写的业务逻辑
			Object retVal = null;
			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
                            //目标方法执行出现异常后,根据事务配置的信息判断是进行提交操作还是回滚操作
                             // 见:内部代码块14:completeTransactionAfterThrowing
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
                           //恢复外出的事务:内层的事务执行完了,将当前ThreadLocal中的事务恢复成外层的事务,为外层事务的再次执行做准备
                           //事务的挂起操作就是这样执行的
				cleanupTransactionInfo(txInfo);
			}
                   //提交事务 见:内部代码块11:commitTransactionAfterReturning
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
			final ThrowableHolder throwableHolder = new ThrowableHolder();

			// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
			try {
				Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
					TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
					try {
						return invocation.proceedWithInvocation();
					}
					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);
					}
				});

				// Check result state: It might indicate a Throwable to rethrow.
				if (throwableHolder.throwable != null) {
					throw throwableHolder.throwable;
				}
				return result;
			}
			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;
			}
		}
	}
 
 内部代码块3:getTransactionAttributeSource
 TransactionAspectSupport.class  这个类是TransactionInterceptor 的父类
 public TransactionAttributeSource getTransactionAttributeSource() {
             //这里直接获取这个属性,那这个属性是在什么时候赋值的呢???
             //见 内部代码块4
		return this.transactionAttributeSource;
	}
 
 内部代码块4:
 public void setTransactionAttributes(Properties transactionAttributes) {
		NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
          //往NameMatchTransactionAttributeSource中设置好事件属性 见 内部代码块5
		tas.setProperties(transactionAttributes);
          //成员属性赋值,TransactionAttributeSource是对事件属性对象的包装
		this.transactionAttributeSource = tas;
	}
  
  内部代码块5:
  /**
	 * Parses the given properties into a name/attribute map.
	 * Expects method names as keys and String attributes definitions as values,
	 * parsable into TransactionAttribute instances via TransactionAttributeEditor.
	 * @see #setNameMap
	 * @see TransactionAttributeEditor
	 */
  //将给定的属性解析为名称/属性映射。期望方法名为键,字符串属性定义为值,可通过TransactionAttributeEditor解析为TransactionAttribute实例。
  public void setProperties(Properties transactionAttributes) {
		TransactionAttributeEditor tae = new TransactionAttributeEditor();
          //获取属性名字的枚举
		Enumeration<?> propNames = transactionAttributes.propertyNames();
          //遍历属性名枚举
		while (propNames.hasMoreElements()) {
                  //获取key,也就是方法名
			String methodName = (String) propNames.nextElement();
                   //获取方法名对应的value,也就是属性值,这里获取到的value的格式 如:PROPAGATION_REQUIRED,readOnly
			String value = transactionAttributes.getProperty(methodName);
                   //处理value 见 内部代码块6
			tae.setAsText(value);
                   //获取事件属性,这个事件属性是当前methodName 所对应的事件属性,因为这个属性是刚刚在 内部代码块6 中设置好的
			TransactionAttribute attr = (TransactionAttribute) tae.getValue();
            	//private Map<String, TransactionAttribute> nameMap = new HashMap<>();
                 //将方法名称和事件属性设置到nameMap (key:方法名称 value:事件属性)
			addTransactionalMethod(methodName, attr);
		}
	}
 
 内部代码块6:setAsText
 TransactionAttributeEditor.class
 /**
	 * Format is PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2.
	 * Null or the empty string means that the method is non transactional.
	 * @see java.beans.PropertyEditor#setAsText(java.lang.String)
	 */
	@Override
	public void setAsText(String text) throws IllegalArgumentException {
		if (StringUtils.hasLength(text)) {
			// tokenize it with ","
                   //通过 逗号 把value值分割成一个数组
			String[] tokens = StringUtils.commaDelimitedListToStringArray(text);
                   //tokens 数组中的值会被注册成为RuleBasedTransactionAttribute 中的一个一个属性,也就是说TransactionAttribute对象的作用就是封装事务属性的
                   //通过观察RuleBasedTransactionAttribute 的继承体系,可以看出这个类里面定义了很多事务属性相关的变量,所以我们在配置文件中配置的事务属性就是来自于这里
			RuleBasedTransactionAttribute attr = new RuleBasedTransactionAttribute();
                   //下面就是循环设值了
			for (int i = 0; i < tokens.length; i++) {
				// Trim leading and trailing whitespace.
				String token = StringUtils.trimWhitespace(tokens[i].trim());
				// Check whether token contains illegal whitespace within text.
				if (StringUtils.containsWhitespace(token)) {
					throw new IllegalArgumentException(
							"Transaction attribute token contains illegal whitespace: [" + token + "]");
				}
				// Check token type.
				if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_PROPAGATION)) {
					attr.setPropagationBehaviorName(token);
				}
				else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_ISOLATION)) {
					attr.setIsolationLevelName(token);
				}
				else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_TIMEOUT)) {
					String value = token.substring(DefaultTransactionAttribute.PREFIX_TIMEOUT.length());
					attr.setTimeout(Integer.parseInt(value));
				}
				else if (token.equals(RuleBasedTransactionAttribute.READ_ONLY_MARKER)) {
					attr.setReadOnly(true);
				}
				else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_COMMIT_RULE)) {
					attr.getRollbackRules().add(new NoRollbackRuleAttribute(token.substring(1)));
				}
				else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_ROLLBACK_RULE)) {
					attr.getRollbackRules().add(new RollbackRuleAttribute(token.substring(1)));
				}
				else {
					throw new IllegalArgumentException("Invalid transaction attribute token: [" + token + "]");
				}
			}
                   //然后把事件属性对象设置进成员变量 
			setValue(attr);
		}
		else {
			setValue(null);
		}
	}
 
 内部代码块7:tas.getTransactionAttribute(method, targetClass)
 NameMatchTransactionAttributeSource.class
   @Override
	@Nullable
	public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		if (!ClassUtils.isUserLevelMethod(method)) {
			return null;
		}

		// Look for direct name match.
		String methodName = method.getName();
          //private Map<String, TransactionAttribute> nameMap = new HashMap<>();
		TransactionAttribute attr = this.nameMap.get(methodName);

		if (attr == null) {
			// Look for most specific name match.
			String bestNameMatch = null;
			for (String mappedName : this.nameMap.keySet()) {
				if (isMatch(methodName, mappedName) &&
						(bestNameMatch == null || bestNameMatch.length() <= mappedName.length())) {
					attr = this.nameMap.get(mappedName);
					bestNameMatch = mappedName;
				}
			}
		}

		return attr;
	}
 
 内部代码块8:determineTransactionManager
 /**
	 * Determine the specific transaction manager to use for the given transaction.
	 */
  //获取到给定事务中配置的事务管理器
	@Nullable
	protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
		// Do not attempt to lookup tx manager if no tx attributes are set
		if (txAttr == null || this.beanFactory == null) {
			return getTransactionManager();
		}

		String qualifier = txAttr.getQualifier();
		if (StringUtils.hasText(qualifier)) {
			return determineQualifiedTransactionManager(this.beanFactory, qualifier);
		}
		else if (StringUtils.hasText(this.transactionManagerBeanName)) {
			return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
		}
		else {
			PlatformTransactionManager defaultTransactionManager = getTransactionManager();
			if (defaultTransactionManager == null) {
				defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
				if (defaultTransactionManager == null) {
					defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
					this.transactionManagerCache.putIfAbsent(
							DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
				}
			}
			return defaultTransactionManager;
		}
	}
 
 内部代码块9:createTransactionIfNecessary
 /**
	 * Create a transaction if necessary based on the given TransactionAttribute.
	 * <p>Allows callers to perform custom TransactionAttribute lookups through
	 * the TransactionAttributeSource.
	 * @param txAttr the TransactionAttribute (may be {@code null})
	 * @param joinpointIdentification the fully qualified method name
	 * (used for monitoring and logging purposes)
	 * @return a TransactionInfo object, whether or not a transaction was created.
	 * The {@code hasTransaction()} method on TransactionInfo can be used to
	 * tell if there was a transaction created.
	 * @see #getTransactionAttributeSource()
	 */
	@SuppressWarnings("serial")
 //如果需要,根据给定的TransactionAttribute创建一个事务
	protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
			@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

		// If no name specified, apply method identification as transaction name.
          //给事务起一个名字,方便管理。如果没有指定名称,则应用方法标识作为事务名称。
		if (txAttr != null && txAttr.getName() == null) {
			txAttr = new DelegatingTransactionAttribute(txAttr) {
				@Override
				public String getName() {
					return joinpointIdentification;
				}
			};
		}
          //表示事务运行时的状态,是TransactionInfo 中的一个属性
		TransactionStatus status = null;
		if (txAttr != null) {
			if (tm != null) {
                           //通过事务管理器获取一个事务
                           //接口,见 内部代码块10:getTransaction
                           //具体实现类,见 第25章->代码块1 :getTransaction
				status = tm.getTransaction(txAttr);
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
							"] because no transaction manager has been configured");
				}
			}
		}
           //见:第25章->代码块2 :prepareTransactionInfo
		return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
	}
 
 内部代码块10:getTransaction
  PlatformTransactionManager.class
 /**
	 * Return a currently active transaction or create a new one, according to
	 * the specified propagation behavior.
	 * <p>Note that parameters like isolation level or timeout will only be applied
	 * to new transactions, and thus be ignored when participating in active ones.
	 * <p>Furthermore, not all transaction definition settings will be supported
	 * by every transaction manager: A proper transaction manager implementation
	 * should throw an exception when unsupported settings are encountered.
	 * <p>An exception to the above rule is the read-only flag, which should be
	 * ignored if no explicit read-only mode is supported. Essentially, the
	 * read-only flag is just a hint for potential optimization.
	 * @param definition the TransactionDefinition instance (can be {@code null} for defaults),
	 * describing propagation behavior, isolation level, timeout etc.
	 * @return transaction status object representing the new or current transaction
	 * @throws TransactionException in case of lookup, creation, or system errors
	 * @throws IllegalTransactionStateException if the given transaction definition
	 * cannot be executed (for example, if a currently active transaction is in
	 * conflict with the specified propagation behavior)
	 * @see TransactionDefinition#getPropagationBehavior
	 * @see TransactionDefinition#getIsolationLevel
	 * @see TransactionDefinition#getTimeout
	 * @see TransactionDefinition#isReadOnly
	 */
  //返回当前活动的事务或创建一个新的事务指定的传播行为。注意,隔离级别(isolation level )或超时(timeout )之类的参数将只应用用于新事务,因此在参与活动事务时被忽略。
	TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
 
 内部代码块11:commitTransactionAfterReturning
 TransactionAspectSupport.class
 /**
	 * Execute after successful completion of call, but not after an exception was handled.
	 * Do nothing if we didn't create a transaction.
	 * @param txInfo information about the current transaction
	 */
	protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
		if (txInfo != null && txInfo.getTransactionStatus() != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
			}
                   //提交事务 见:内部代码块12:commit
			txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
		}
	}
 
 内部代码块12:commit
 AbstractPlatformTransactionManager.class
 /**
	 * This implementation of commit handles participating in existing
	 * transactions and programmatic rollback requests.
	 * Delegates to {@code isRollbackOnly}, {@code doCommit}
	 * and {@code rollback}.
	 * @see org.springframework.transaction.TransactionStatus#isRollbackOnly()
	 * @see #doCommit
	 * @see #rollback
	 */
	@Override
	public final void commit(TransactionStatus status) throws TransactionException {
		if (status.isCompleted()) {
			throw new IllegalTransactionStateException(
					"Transaction is already completed - do not call commit or rollback more than once per transaction");
		}

		DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
		if (defStatus.isLocalRollbackOnly()) {
			if (defStatus.isDebug()) {
				logger.debug("Transactional code has requested rollback");
			}
			processRollback(defStatus, false);
			return;
		}

		if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
			if (defStatus.isDebug()) {
				logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
			}
			processRollback(defStatus, true);
			return;
		}
            //提交事务,最后这里面会执行:doCommit()方法 见 内部代码块13:doCommit
		processCommit(defStatus);
	}
    
   内部代码块13:doCommit
   DataSourceTransactionManager.class
   @Override
	protected void doCommit(DefaultTransactionStatus status) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
		Connection con = txObject.getConnectionHolder().getConnection();
		if (status.isDebug()) {
			logger.debug("Committing JDBC transaction on Connection [" + con + "]");
		}
		try {
                  //通过连接对象的事务提交方法,提交事务
			con.commit();
		}
		catch (SQLException ex) {
			throw new TransactionSystemException("Could not commit JDBC transaction", ex);
		}
	} 
 
 内部代码块14:completeTransactionAfterThrowing
 TransactionAspectSupport.class
 /**
	 * Handle a throwable, completing the transaction.
	 * We may commit or roll back, depending on the configuration.
	 * @param txInfo information about the current transaction
	 * @param ex throwable encountered
	 */
	protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
		if (txInfo != null && txInfo.getTransactionStatus() != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
						"] after exception: " + ex);
			}
			if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
				try {
                                    //回滚事务
					txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
				}
				catch (TransactionSystemException ex2) {
					logger.error("Application exception overridden by rollback exception", ex);
					ex2.initApplicationException(ex);
					throw ex2;
				}
				catch (RuntimeException | Error ex2) {
					logger.error("Application exception overridden by rollback exception", ex);
					throw ex2;
				}
			}
			else {
				// We don't roll back on this exception.
				// Will still roll back if TransactionStatus.isRollbackOnly() is true.
				try {
                                    //提交事务
					txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
				}
				catch (TransactionSystemException ex2) {
					logger.error("Application exception overridden by commit exception", ex);
					ex2.initApplicationException(ex);
					throw ex2;
				}
				catch (RuntimeException | Error ex2) {
					logger.error("Application exception overridden by commit exception", ex);
					throw ex2;
				}
			}
		}
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring事务管理是建立在底层数据库事务之上的。在 Spring 中,事务的管理是通过 AOP 实现的,即通过动态代理技术,在运行时动态地将事务相关的代码织入到目标对象的方法中,从而实现事务的控制。 具体地说,Spring事务管理是通过 TransactionInterceptor 和 TransactionManager 两个组件来实现的。其中,TransactionInterceptor 是一个拦截器,负责拦截业务方法的调用,并在方法执行前后进行事务处理;而 TransactionManager 则负责管理底层数据库连接和事务的提交、回滚等操作。 当一个业务方法被调用时,TransactionInterceptor 会首先判断该方法是否需要进行事务管理。如果需要,则会获取一个事务连接,并在该连接上开启一个新的事务;如果不需要,则直接执行业务逻辑。当业务逻辑执行完成后,TransactionInterceptor 会根据业务方法的执行结果决定是否提交事务或回滚事务。 需要注意的是,Spring事务管理还支持声明式事务和编程式事务两种方式。声明式事务通过配置 AOP 切面和事务属性来实现,可以将事务管理与业务逻辑分离开来,提高代码的可读性和维护性;而编程式事务则需要手动在代码中控制事务的开启、提交和回滚等操作,相对来说更为灵活,但也更加复杂。 总之,Spring事务管理是建立在底层数据库事务之上的,通过 AOP 技术和 TransactionInterceptor、TransactionManager 等组件来实现事务的控制。同时,Spring 还支持声明式事务和编程式事务两种方式,可以根据具体需求来选择使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值