Spring源碼:聲明式事務@Transactional源碼分析--spring xml實現

目錄

0. 聲明式事務的開啓

1.事務註解BeanDefinition解析器AnnotationDrivenBeanDefinitionParser

1.1 InfrastructureAdvisorAutoProxyCreator

1.2 AnnotationTransactionAttributeSource

1.3 TransactionInterceptor

1.4 BeanFactoryTransactionAttributeSourceAdvisor

 

0. 聲明式事務的開啓

spring配置文件中<tx:annotation-driven/>開啓事務註解驅動,並通過TxNamespaceHandler對該tag進行處理,TxNamespaceHandler類初始化方法引入了AnnotationDrivenBeanDefinitionParser,如下:

public class TxNamespaceHandler extends NamespaceHandlerSupport {

	static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";

	static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";


	static String getTransactionManagerName(Element element) {
		return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
				element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
	}


	@Override
	public void init() {
		registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
		registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
	}

}

1.事務註解BeanDefinition解析器AnnotationDrivenBeanDefinitionParser

該解析器通過解析<tx/>標籤,主要引入瞭如下的beandefinition:

  • InfrastructureAdvisorAutoProxyCreator 切面自動代理創建類
  • AnnotationTransactionAttributeSource 事務註解屬性源
  • TransactionInterceptor 事務攔截器
  • BeanFactoryTransactionAttributeSourceAdvisor 事務屬性源切面

1.1 InfrastructureAdvisorAutoProxyCreator

首先看一下繼承結構,如下,可以看出該繼承結構和上篇文章Spring源碼:Aop源碼分析 Aop代理創建的繼承結構是一樣的,因此InfrastructureAdvisorAutoProxyCreator主要完成動態代理的創建,具體分析參考上篇;

1.2 AnnotationTransactionAttributeSource

該事務屬性源對象實現TransactionAttributeSource的接口方法TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass),計算目標類和目標方法的事務屬性配置信息,包括傳播行爲、隔離級別、超時時間以及異常回滾等;

1.3 TransactionInterceptor

事務攔截器,主要完成目標方法的攔截,進行事務的植入,具體攔截邏輯在TransactionAspectSupport抽象類中,同時它是線程安全的,主要是藉助

private static final ThreadLocal<TransactionInfo> transactionInfoHolder = new NamedThreadLocal<TransactionInfo>("Current aspect-driven transaction")來保證的;同時通過屬性注入的方式注入了AnnotationTransactionAttributeSource,完成事務配置信息的獲取;

/**
	 * 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
	 */
	protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
			throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			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
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				cleanupTransactionInfo(txInfo);
			}
			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,
						new TransactionCallback<Object>() {
							@Override
							public Object doInTransaction(TransactionStatus 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;
			}
		}
	}

1.4 BeanFactoryTransactionAttributeSourceAdvisor

BeanFactoryTransactionAttributeSourceAdvisor是一個事務切面,通過屬性注入的方式包裝瞭如上的AnnotationTransactionAttributeSource以及TransactionInterceptor,前者主要用於切點的定義,後者用來表示增強Advice;這樣,通過InfrastructureAdvisorAutoProxyCreator類就可以過濾出符合指定class的攔截器鏈

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章