目錄
1.事務註解BeanDefinition解析器AnnotationDrivenBeanDefinitionParser
1.1 InfrastructureAdvisorAutoProxyCreator
1.2 AnnotationTransactionAttributeSource
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的攔截器鏈