在spring中开启事务可以通过在xml中配置以及使用注解的方式,我们下面按照xml配置的方式进行讲解。
我们来回顾一下spring aop实现的过程
1:所有的bean在初始化之后会调用后置处理器的postProcessAfterInitialization
2: 查找合适的增强器
3:根据查找到的增强器为当前的类实现代理(jdk或者cglib)。其中会将advisor的advice进行封装,从而加入到拦截器链中。
4:执行被代理的对象的方法,进入代理对象的invoke或者interceptor方法。
5:经过拦截器链进行拦截。
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>
<tx:annotation-driven transaction-manager="transactionManager" /> |
定义transcationManager并且开启事务功能,下面我们分析tx:annotation-driven标签
进入TxNamespaceHandler可以查看到对应的解析类为AnnotationDrivenBeanDefinitionParser
进入AnnotationDrivenBeanDefinitionParser的parse方法。
public BeanDefinition parse(Element element, ParserContext parserContext) { //注册一个TransactionalEventListenerFactory bean registerTransactionalEventListenerFactory(parserContext); //根据选择的mode分别用不同的方式 String mode = element.getAttribute("mode"); if ("aspectj".equals(mode)) { // mode="aspectj" registerTransactionAspect(element, parserContext); } else { // mode="proxy" AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext); } return null; } |
由于我们的mode没传,所以默认为proxy。进入AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) { AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME; if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) { Object eleSource = parserContext.extractSource(element);
// Create the TransactionAttributeSource definition. RootBeanDefinition sourceDef = new RootBeanDefinition( "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"); sourceDef.setSource(eleSource); sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
// Create the TransactionInterceptor definition. RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class); interceptorDef.setSource(eleSource); interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registerTransactionManager(element, interceptorDef); interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
// Create the TransactionAttributeSourceAdvisor definition. RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class); advisorDef.setSource(eleSource); advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); advisorDef.getPropertyValues().add("adviceBeanName", interceptorName); if (element.hasAttribute("order")) { advisorDef.getPropertyValues().add("order", element.getAttribute("order")); } parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource); compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName)); compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName)); compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName)); parserContext.registerComponent(compositeDef); } } |
以上代码创建了三个bean
AnnotationTransactionAttributeSource,TransactionInterceptor以及BeanFactoryTransactionAttributeSourceAdvisor
其中BeanFactoryTransactionAttributeSourceAdvisor的属性包含了AnnotationTransactionAttributeSource和TransactionInterceptor
还记得我们分析aop的实现原理的时候。InfrastructureAdvisorAutoProxyCreator也是继承了AbstractAdvisorAutoProxyCreator从而实现了SmartInstantiationAwareBeanPostProcessor接口。在创建Bean的时候同样会被其postProcessAfterInitialization所拦截。所以这个又回到之前分析AbstractAdvisorAutoProxyCreator的时候了,首先去找到对应的增强器,如果找到增强器,就应用对应的增强。
还记得在之前说aop的时候,查找增强器的时候(在BeanFactoryAdvisorRetrievalHelper的findAdvisorBeans方法中)。会把实现了所有Advisor的bean拿出来。作为增强器。我们上面说会注册BeanFactoryTransactionAttributeSourceAdvisor这个bean。这个bean正好实现了Advisor接口,于是就会作为增强器取出。
下面我们看下是否可以使用增强以及应用增强器
进入AopUtil的canApply
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor) advisor; return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { // It doesn't have a pointcut so we assume it applies. return true; } } |
当前的BeanFactoryTransactionAttributeSourceAdvisor是PointcutAdvisor类型,于是进入
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { Assert.notNull(pc, "Pointcut must not be null"); //对于BeanFactoryTransactionAttributeSourceAdvisor 永远为true if (!pc.getClassFilter().matches(targetClass)) { return false; }
MethodMatcher methodMatcher = pc.getMethodMatcher(); IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; }
Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); classes.add(targetClass); for (Class<?> clazz : classes) { Method[] methods = clazz.getMethods(); for (Method method : methods) { if ((introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) || methodMatcher.matches(method, targetClass)) { return true; } } }
return false; } |
在分析之前我们需要进入到TransactionAttributeSourceAdvisor的构造函数。如下,可以看出
他的pointCut是继承自TransactionAttributeSourcePointcut,并且将之前的TransactionAttributeSource创建了出来。
public TransactionAttributeSourceAdvisor(TransactionInterceptor interceptor) { class NamelessClass_1 extends TransactionAttributeSourcePointcut { NamelessClass_1() { }
@Nullable protected TransactionAttributeSource getTransactionAttributeSource() { return TransactionAttributeSourceAdvisor.this.transactionInterceptor != null ? TransactionAttributeSourceAdvisor.this.transactionInterceptor.getTransactionAttributeSource() : null; } }
this.pointcut = new NamelessClass_1(); this.setTransactionInterceptor(interceptor); } |
最终会调用对应的TransactionAttributeSourcePointcut的matches方法
public boolean matches(Method method, Class<?> targetClass) { if (TransactionalProxy.class.isAssignableFrom(targetClass)) { return false; } //调用AnnotationTransactionAttributeSource的getTransactionAttribute TransactionAttributeSource tas = getTransactionAttributeSource(); return (tas == null || tas.getTransactionAttribute(method, targetClass) != null); } |
继续跟踪代码进入AnnotationTransactionAttributeSource的getTransactionAttribute方法中
public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) { // First, see if we have a cached value. Object cacheKey = getCacheKey(method, targetClass); Object cached = this.attributeCache.get(cacheKey); if (cached != null) { // Value will either be canonical value indicating there is no transaction attribute, // or an actual transaction attribute. if (cached == NULL_TRANSACTION_ATTRIBUTE) { return null; } else { return (TransactionAttribute) cached; } } else { // We need to work it out. TransactionAttribute txAtt = computeTransactionAttribute(method, targetClass); // Put it in the cache. if (txAtt == null) { this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE); } else { if (logger.isDebugEnabled()) { Class<?> classToLog = (targetClass != null ? targetClass : method.getDeclaringClass()); logger.debug("Adding transactional method '" + classToLog.getSimpleName() + "." + method.getName() + "' with attribute: " + txAtt); } this.attributeCache.put(cacheKey, txAtt); } return txAtt; } } |
进入到对应的computeTransactionAttribute方法
protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) { // 判断是否值允许public方法 if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) { return null; }
//忽略cglib的生成的 Class<?> userClass = ClassUtils.getUserClass(targetClass); //method是接口的方法,specificMethod是实现类的方法 Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass); // If we are dealing with method with generic parameters, find the original method. specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
//查看方法中是否有事务声明(Transactional注解) TransactionAttribute txAtt = findTransactionAttribute(specificMethod); if (txAtt != null) { return txAtt; }
//查看方法所在类中是否有事务声明(Transactional注解) txAtt = findTransactionAttribute(specificMethod.getDeclaringClass()); if (txAtt != null) { return txAtt; } //如果存在接口,则去接口中查找 if (specificMethod != method) { // Fallback is to look at the original method. txAtt = findTransactionAttribute(method); if (txAtt != null) { return txAtt; } // Last fallback is the class of the original method. return findTransactionAttribute(method.getDeclaringClass()); } return null; } |
好了,分析完是否使用增强器后,下面我们就看增强器的具体增强了。还记得我们之前分析的aop进行创建代理类的过程吗?,如果是jdk代理会利用InvokeHanlder创建一个JdkDynamicAopProxy代理对象,最终会调用JdkDynamicAopProxy的invoke方法,而对于CGLib代理会继承并且对其添加一系列的回调接口,其中有DynamicAdvisedInterceptor接口,那么我们选择JdkDynamicAopProxy分析,会执行下面的方法
进入到ReflectiveMethodInvocation的proceed方法。
public Object proceed() throws Throwable { // We start with an index of -1 and increment early. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); }
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } } |
由于在之前会把advisor中的advice获取到,然后作为methodInteceptor加入到拦截链路中,。所以在interceptorsAndDynamicMethodMatchers中会存放TransactionInterceptor。所以这里边会调用TransactionInterceptor的invoke方法。详情可查看(DefaultAdvisorAdapterRegistry的getInterceptors方法)
进入TransactionAspectSupport中的invokeWithinTransaction查看
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final TransactionAspectSupport.InvocationCallback invocation) throws Throwable { //获取事务属性,传播行为,是否只读等 final TransactionAttribute txAttr = this.getTransactionAttributeSource().getTransactionAttribute(method, targetClass); //获取事务管理器 final PlatformTransactionManager tm = this.determineTransactionManager(txAttr); //获取方法的唯一标识(类.方法名) final String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr); Object result; //编程式事务 if (txAttr != null && tm instanceof CallbackPreferringPlatformTransactionManager) { final TransactionAspectSupport.ThrowableHolder throwableHolder = new TransactionAspectSupport.ThrowableHolder();
try { result = ((CallbackPreferringPlatformTransactionManager)tm).execute(txAttr, new TransactionCallback<Object>() { public Object doInTransaction(TransactionStatus status) { TransactionAspectSupport.TransactionInfo txInfo = TransactionAspectSupport.this.prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
Object var4; try { Object var3 = invocation.proceedWithInvocation(); return var3; } catch (Throwable var8) { if (txAttr.rollbackOn(var8)) { if (var8 instanceof RuntimeException) { throw (RuntimeException)var8; }
throw new TransactionAspectSupport.ThrowableHolderException(var8); }
throwableHolder.throwable = var8; var4 = null; } finally { TransactionAspectSupport.this.cleanupTransactionInfo(txInfo); }
return var4; } }); if (throwableHolder.throwable != null) { throw throwableHolder.throwable; } else { return result; } } catch (TransactionAspectSupport.ThrowableHolderException var18) { throw var18.getCause(); } catch (TransactionSystemException var19) { if (throwableHolder.throwable != null) { this.logger.error("Application exception overridden by commit exception", throwableHolder.throwable); var19.initApplicationException(throwableHolder.throwable); }
throw var19; } catch (Throwable var20) { if (throwableHolder.throwable != null) { this.logger.error("Application exception overridden by commit exception", throwableHolder.throwable); }
throw var20; } } else { //声明式事务 //创建一个事务 TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(tm, txAttr, joinpointIdentification); result = null;
try { result = invocation.proceedWithInvocation(); } catch (Throwable var16) { this.completeTransactionAfterThrowing(txInfo, var16); throw var16; } finally { //清除事务信息 this.cleanupTransactionInfo(txInfo); } //返回之后提交事务 this.commitTransactionAfterReturning(txInfo); return result; } } |
下面我们分析一下创建事务的过程。进入TransactionAspectSupport的createTransactionIfNecessary方法中
protected TransactionAspectSupport.TransactionInfo createTransactionIfNecessary(PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) { if (txAttr != null && ((TransactionAttribute)txAttr).getName() == null) { //如果没有名称指定则使用方法唯一标识,使用DelegatingTransactionAttribute封装事//务 txAttr = new DelegatingTransactionAttribute((TransactionAttribute)txAttr) { public String getName() { return joinpointIdentification; } }; } //获取事务状态 TransactionStatus status = null; if (txAttr != null) { if (tm != null) { status = tm.getTransaction((TransactionDefinition)txAttr); } else if (this.logger.isDebugEnabled()) { this.logger.debug("Skipping transactional joinpoint [" + joinpointIdentification + "] because no transaction manager has been configured"); } } //创建一个TransactionInfo根据status和txAttr return this.prepareTransactionInfo(tm, (TransactionAttribute)txAttr, joinpointIdentification, status); } |
下面我们继续跟进代码,查看一下事务的获取步骤
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { Object transaction = this.doGetTransaction(); boolean debugEnabled = this.logger.isDebugEnabled(); if (definition == null) { definition = new DefaultTransactionDefinition(); } //判断当前的transaction是否已经有连接并且事务已经激活 if (this.isExistingTransaction(transaction)) { //说明存在事务,直接返回 return this.handleExistingTransaction((TransactionDefinition)definition, transaction, debugEnabled); } else if (((TransactionDefinition)definition).getTimeout() < -1) { //判断超时时间 throw new InvalidTimeoutException("Invalid transaction timeout", ((TransactionDefinition)definition).getTimeout()); } else if (((TransactionDefinition)definition).getPropagationBehavior() == 2) { //到这里说明当前线程不存在事务,但是事物的传播行为为: MANDATORY //参考TransactionDefinition的定义 throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'"); } else if (((TransactionDefinition)definition).getPropagationBehavior() != 0 && ((TransactionDefinition)definition).getPropagationBehavior() != 3 && ((TransactionDefinition)definition).getPropagationBehavior() != 6) { if (((TransactionDefinition)definition).getIsolationLevel() != -1 && this.logger.isWarnEnabled()) { this.logger.warn("Custom isolation level specified but no actual transaction initiated; isolation level will effectively be ignored: " + definition); }
boolean newSynchronization = this.getTransactionSynchronization() == 0; return this.prepareTransactionStatus((TransactionDefinition)definition, (Object)null, true, newSynchronization, debugEnabled, (Object)null); } else { //进入到这里说明事务是required,或者是new,或者是nested //这里边都需重新创建事务 AbstractPlatformTransactionManager.SuspendedResourcesHolder suspendedResources = this.suspend((Object)null); if (debugEnabled) { this.logger.debug("Creating new transaction with name [" + ((TransactionDefinition)definition).getName() + "]: " + definition); }
try { boolean newSynchronization = this.getTransactionSynchronization() != 2; //创建transactionStatus DefaultTransactionStatus status = this.newTransactionStatus((TransactionDefinition)definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); //开启事务 this.doBegin(transaction, (TransactionDefinition)definition); //事务的同步设置,其实是将当前事务的等级,隔离级别等设置到线程 //变量中 this.prepareSynchronization(status, (TransactionDefinition)definition); return status; } catch (RuntimeException var7) { this.resume((Object)null, suspendedResources); throw var7; } catch (Error var8) { this.resume((Object)null, suspendedResources); throw var8; } } } |
进入对应的DataSourceTransactionManager的doBegin查看代码
protected void doBegin(Object transaction, TransactionDefinition definition) { DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction; Connection con = null;
try { //如果当前没有connection则获取一个connection if (!txObject.hasConnectionHolder() || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { Connection newCon = this.dataSource.getConnection(); if (this.logger.isDebugEnabled()) { this.logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction"); } //保存连接 txObject.setConnectionHolder(new ConnectionHolder(newCon), true); } //设置事务标识 txObject.getConnectionHolder().setSynchronizedWithTransaction(true); con = txObject.getConnectionHolder().getConnection(); //获取当前的传播行为 Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); txObject.setPreviousIsolationLevel(previousIsolationLevel); if (con.getAutoCommit()) { txObject.setMustRestoreAutoCommit(true); if (this.logger.isDebugEnabled()) { this.logger.debug("Switching JDBC Connection [" + con + "] to manual commit"); }
con.setAutoCommit(false); }
this.prepareTransactionalConnection(con, definition); txObject.getConnectionHolder().setTransactionActive(true); int timeout = this.determineTimeout(definition); if (timeout != -1) { txObject.getConnectionHolder().setTimeoutInSeconds(timeout); } //将当前线程获取到的连接和当前线程进行绑定 if (txObject.isNewConnectionHolder()) { TransactionSynchronizationManager.bindResource(this.getDataSource(), txObject.getConnectionHolder()); }
} catch (Throwable var7) { if (txObject.isNewConnectionHolder()) { DataSourceUtils.releaseConnection(con, this.dataSource); txObject.setConnectionHolder((ConnectionHolder)null, false); }
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", var7); } } |
下面我们分析一下,当事务的回滚操作是怎样进行的。进入ransactionAspectSupport的completeTransactionAfterThrowing方法中查看。
protected void completeTransactionAfterThrowing(TransactionAspectSupport.TransactionInfo txInfo, Throwable ex) { //回滚的前提是有事务 if (txInfo != null && txInfo.hasTransaction()) { if (this.logger.isTraceEnabled()) { this.logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "] after exception: " + ex); } //回滚只针对runtimeException或者Error //return ex instanceof RuntimeException || ex instanceof Error; if (txInfo.transactionAttribute.rollbackOn(ex)) { try { //根据事物信息进行回滚 txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus()); } catch (TransactionSystemException var7) { this.logger.error("Application exception overridden by rollback exception", ex); var7.initApplicationException(ex); throw var7; } catch (RuntimeException var8) { this.logger.error("Application exception overridden by rollback exception", ex); throw var8; } catch (Error var9) { this.logger.error("Application exception overridden by rollback error", ex); throw var9; } } else { try { //不是runtimeException以及error。即使有问题,也进行提交 txInfo.getTransactionManager().commit(txInfo.getTransactionStatus()); } catch (TransactionSystemException var4) { this.logger.error("Application exception overridden by commit exception", ex); var4.initApplicationException(ex); throw var4; } catch (RuntimeException var5) { this.logger.error("Application exception overridden by commit exception", ex); throw var5; } catch (Error var6) { this.logger.error("Application exception overridden by commit error", ex); throw var6; } } }
} |
//继续跟进代码,进入AbstractPlatformTransactionManager的rollback方法
public final void rollback(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"); } else { DefaultTransactionStatus defStatus = (DefaultTransactionStatus)status; this.processRollback(defStatus); } }
private void processRollback(DefaultTransactionStatus status) { try { try { //首先是自定义触发器的调用。可通过TransactionSynchronizationManager的静态方法//registerSynchronization直接注册
this.triggerBeforeCompletion(status);
//首先判断是否有保存点,如果you保存点,rollback到保存点 if (status.hasSavepoint()) { if (status.isDebug()) { this.logger.debug("Rolling back transaction to savepoint"); }
status.rollbackToHeldSavepoint(); } else if (status.isNewTransaction()) { if (status.isDebug()) { this.logger.debug("Initiating transaction rollback"); } //当前事务是独立新事物,直接rollback this.doRollback(status); } else if (status.hasTransaction()) { if (!status.isLocalRollbackOnly() && !this.isGlobalRollbackOnParticipationFailure()) { if (status.isDebug()) { this.logger.debug("Participating transaction failed - letting transaction originator decide on rollback"); } } else { if (status.isDebug()) { this.logger.debug("Participating transaction failed - marking existing transaction as rollback-only"); }
this.doSetRollbackOnly(status); } } else { this.logger.debug("Should roll back transaction but cannot - no transaction available"); } } catch (RuntimeException var7) { this.triggerAfterCompletion(status, 2); throw var7; } catch (Error var8) { this.triggerAfterCompletion(status, 2); throw var8; }
this.triggerAfterCompletion(status, 1); } finally { this.cleanupAfterCompletion(status); }
} |