首页 >> 大全

Spring Transaction 从实例读源码

2023-12-22 大全 23 作者:考证青年

我们只关注源码中的核心的业务逻辑,由于过于复杂,所以哪怕只掌握其核心逻辑就很不容易了。另外文章是从实例看源码的,所以可能源码中有多条执行路径,但我们只关注实例中经过的逻辑,其他的执行路径可能会被忽略。

概述

是在 tx模块中实现的,事务功能依赖于的AOP模块,阅读tx模块源码前最好先阅读 AOP的源码。

的功能可以分为两个部分,一个部分是解析事务标签,另一部分是创建事务代理。

解析事务标签与解析AOP标签非常类似,它解析 标签,注册了一个类和三个bean。这三个bean支撑起了整个的事务功能。其中的两个bean(or和)被注入到了一个名为isor这个bean中。这个类实现了接口。只要类或方法实现了@接口,该一定会被加到拦截器链中,对原方法进行事务增强。

isor作为一个,用于对事务方法进行增强。

而作为一个

ator,会在时调用其方法,该方法会创建事务代理。

创建事务代理是对事务方法前后添加 开启、回滚、提交事务的功能,主要依赖于or来增强事务功能。

前置知识 事务介绍

编程式事务:所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理。管理使用或者直接使用底层的。对于编程式事务管理,推荐使用。

声明式事务:管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@注解的方式),便可以将事务规则应用到业务逻辑中。

显然声明式事务管理要优于编程式事务管理,这正是倡导的非侵入式的开发方式。

声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。

事务传播行为

如果当前存在一个事务,则加入当前事务;如果不存在任何事务,则创建一个新的事务。总之,要至少保证在一个事务中运行。通常作为默认的事务传播行为。

如果当前存在一个事务,则加入当前事务;如果当前不存在事务,则直接执行。 对于一些查询方法来说,通常是比较合适的传播行为选择。 如果当前方法直接执行,那么不需要事务的支持;如果当前方法被其他方法调用,而其他方法启动了一个事务的时候,使用可以保证当前方法能够加入当前事务并洞察当前事务对数据资源所做的更新。 比如说,A.()会首先更新数据库,然后调用B.()进行查询,那么,B.()如果是的传播行为, 就可以读取A.()之前所做的最新更新结果,而如果使用稍后所提到的ORTED,则B.()将无法读取最新的更新结果,因为A.()的事务在这个时候还没有提交(除非隔离级别是read )。

Y

Y强制要求当前存在一个事务,如果不存在,则抛出异常。 如果某个方法需要事务支持,但自身又不管理事务提交或者回滚的时候,比较适合使用

Y。

_NEW

不管当前是否存在事务,都会创建新的事务。如果当前存在事务的话,会将当前的事务挂起()。 如果某个业务对象所做的事情不想影响到外层事务的话,_NEW应该是合适的选择,比如,假设当前的业务方法需要向数据库中更新某些日志信息, 但即使这些日志信息更新失败,我们也不想因为该业务方法的事务回滚而影响到外层事务的成功提交,因为这种情况下,当前业务方法的事务成功与否对外层事务来说是无关紧要的。

ORTED

不支持当前事务,而是在没有事务的情况下执行。如果当前存在事务的话,当前事务原则上将被挂起(),但要依赖于对应的实现类是否支持事务的挂起(),更多情况请参照n的文档。 ORTED与之间的区别,可以参照部分的实例内容。

永远不需要当前存在事务,如果存在当前事务,则抛出异常。

如果存在当前事务,则在当前事务的一个嵌套事务中执行,否则与的行为类似,即创建新的事务,在新创建的事务中执行。 粗看起来好像与_NEW的行为类似,实际上二者是有差别的。 _NEW创建的新事务与外层事务属于同一个“档次”,即二者的地位是相同的,当新创建的事务运行的时候,外层事务将被暂时挂起(); 而创建的嵌套事务则不然,它是寄生于当前外层事务的,它的地位比当前外层事务的地位要小一号,当内部嵌套事务运行的时候,外层事务也是处于状态。

解析事务标签

这里写图片描述

<tx:annotation-driven />

同AOP标签,需要一个对应的。

.parse

public BeanDefinition parse(Element element, ParserContext parserContext) {registerTransactionalEventListenerFactory(parserContext);String mode = element.getAttribute("mode");if ("aspectj".equals(mode)) {// mode="aspectj"registerTransactionAspect(element, parserContext);}else {// mode="proxy"AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);}return null;
}

er.eator

逻辑:

注册了一个和三个bean。这三个bean支撑起了整个的事务功能。

其中的两个bean(or和)被注入到了一个名为isor这个bean中。

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
// 注册InfrastructureAdvisorAutoProxyCreator这个类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.
//创建TransactionAttributeSource的bean
RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");sourceDef.setSource(eleSource);sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 注册bean,并使用Spring中的定义规则生成beanNameString sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);// 创建TransactionInterceptor的beanRootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);interceptorDef.setSource(eleSource);interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);registerTransactionManager(element, interceptorDef);interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
// 注册bean,并使用Spring中的定义规则生成beanNameString interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);// Create the TransactionAttributeSourceAdvisor definition.// 创建TransactionAttributeSourceAdvisor的bean
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);advisorDef.setSource(eleSource);advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 将sourceName的bean注入advisorDef的transactionAttributeSourceadvisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
// 将interceptorName的bean注入advisorDef的adviceBeanNameadvisorDef.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);}
}

.

public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);registerComponentIfNecessary(beanDefinition, parserContext);
}

.

这里注册了(基础设施)这个类。

public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}

isor(用于对事务方法进行增强)

BeanFactoryTransactionAttributeSourceAdvisor

在AOP的.中获取了所有类型为的bean,包括isor这个类,并随着其他的一起在后续的步骤中被织入代理。

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {private TransactionAttributeSource transactionAttributeSource;private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {@Overrideprotected TransactionAttributeSource getTransactionAttributeSource() {return transactionAttributeSource;}};/*** Set the transaction attribute source which is used to find transaction* attributes. This should usually be identical to the source reference* set on the transaction interceptor itself.* @see TransactionInterceptor#setTransactionAttributeSource*/public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {this.transactionAttributeSource = transactionAttributeSource;}/*** Set the {@link ClassFilter} to use for this pointcut.* Default is {@link ClassFilter#TRUE}.*/public void setClassFilter(ClassFilter classFilter) {this.pointcut.setClassFilter(classFilter);}@Overridepublic Pointcut getPointcut() {return this.pointcut;}}

与IOC的衔接

作为一个ator,会在时调用其方法,该方法会创建事务代理。

.

public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {Object cacheKey = getCacheKey(beanClass, beanName);if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {if (this.advisedBeans.containsKey(cacheKey)) {return null;}if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return null;}}// Create proxy here if we have a custom TargetSource.// Suppresses unnecessary default instantiation of the target bean:// The TargetSource will handle target instances in a custom fashion.if (beanName != null) {TargetSource targetSource = getCustomTargetSource(beanClass, beanName);if (targetSource != null) {this.targetSourcedBeans.add(beanName);Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}}return null;
}

会寻找所有实现接口的类。

我们之前注册了isor这个类,这个类实现了接口。isor作为一个,用于对事务方法进行增强。只要类或方法实现了@接口,该一定会被加到拦截器链中,对原方法进行事务增强。

返回的类型是isor,而其是or。

这里写图片描述

之后调用了pply 方法,又调用方法。

1) (判断bean是否需要添加事务增强)

(isor,)

关键在于是否从指定的类或类中的方法找到对应的事务属性

public static boolean canApply(Advisor advisor, Class targetClass, boolean hasIntroductions) {
// 处理引入增强if (advisor instanceof IntroductionAdvisor) {return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);}
// 处理PointcutAdvisor,是指有切入点的Advisorelse 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;}
}

pca.()对于isor而言,是。

private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {@Overrideprotected TransactionAttributeSource getTransactionAttributeSource() {return transactionAttributeSource;}
};

pc.()对于而言,就是this。

public final MethodMatcher getMethodMatcher() {return this;
}

public static boolean canApply(Pointcut pc, Class targetClass, boolean hasIntroductions) {Assert.notNull(pc, "Pointcut must not be null");if (!pc.getClassFilter().matches(targetClass)) {return false;}MethodMatcher methodMatcher = pc.getMethodMatcher();if (methodMatcher == MethodMatcher.TRUE) {// No need to iterate the methods if we're matching any method anyway...return true;}IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;if (methodMatcher instanceof IntroductionAwareMethodMatcher) {introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;}// 获取bean目标类和所有接口,放到集合中Set> classes = new LinkedHashSet>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));classes.add(targetClass);
// 遍历集合,获取每个类/接口的所有方法,并对方法进行逐个匹配for (Class clazz : classes) {Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);for (Method method : methods) {if ((introductionAwareMethodMatcher != null &&introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||// 实际的匹配方法methodMatcher.matches(method, targetClass)) {return true;}}}return false;
}

.(, )会使用

类的方法。

1.1) (匹配方法)

这里的tas就是。

如果该bean的该方法中存在事务属性,那么该类/方法需要继续事务增强。

public boolean matches(Method method, Class targetClass) {if (TransactionalProxy.class.isAssignableFrom(targetClass)) {return false;}TransactionAttributeSource tas = getTransactionAttributeSource();return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

1.1.1) .ute(获取事务属性,封装了@中的配置信息)

先尝试从缓存加载,如果对应信息没有被缓存的话,工作又委托给了方法。

public TransactionAttribute getTransactionAttribute(Method method, Class targetClass) {if (method.getDeclaringClass() == Object.class) {return null;}// 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 txAttr = computeTransactionAttribute(method, targetClass);// Put it in the cache.if (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.isDebugEnabled()) {logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);}this.attributeCache.put(cacheKey, txAttr);}return txAttr;}
}

1.1.1.1) (提取事务注解)

逻辑:如果方法中存在事务属性,则使用方法上的属性,否则使用方法所在的类上的属性。如果方法所在类的属性上还是没有搜寻到对应的事务属性,那么再搜寻接口中的方法,再没有的话,最后尝试搜寻接口的类上面的声明。

protected TransactionAttribute computeTransactionAttribute(Method method, Class targetClass) {// Don't allow no-public methods as required.if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {return null;}// Ignore CGLIB subclasses - introspect the actual user class.Class userClass = ClassUtils.getUserClass(targetClass);// The method may be on an interface, but we need attributes from the target class.// If the target class is null, the method will be unchanged.
// 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);// 查看方法中是否存在事务声明// First try is the method in the target class.TransactionAttribute txAttr = findTransactionAttribute(specificMethod);if (txAttr != null) {return txAttr;}// 查看方法所在类中是否存在事务声明// Second try is the transaction attribute on the target class.txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {return txAttr;}// 如果存在接口,则到接口中寻找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;}}return null;
}

protected TransactionAttribute findTransactionAttribute(Method method) {return determineTransactionAttribute(method);
}

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {if (ae.getAnnotations().length > 0) {for (TransactionAnnotationParser annotationParser : this.annotationParsers) {TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);if (attr != null) {return attr;}}}return null;
}

1.1.1.1.1) .(解析注解)

以为例:

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
//寻找@Transactional注解,有则解析该注解AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, Transactional.class);if (attributes != null) {return parseTransactionAnnotation(attributes);}else {return null;}
}

解析@中的各个属性,并封装到中返回。

protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();Propagation propagation = attributes.getEnum("propagation");rbta.setPropagationBehavior(propagation.value());Isolation isolation = attributes.getEnum("isolation");rbta.setIsolationLevel(isolation.value());rbta.setTimeout(attributes.getNumber("timeout").intValue());rbta.setReadOnly(attributes.getBoolean("readOnly"));rbta.setQualifier(attributes.getString("value"));ArrayList rollBackRules = new ArrayList();Class[] rbf = attributes.getClassArray("rollbackFor");for (Class rbRule : rbf) {RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);rollBackRules.add(rule);}String[] rbfc = attributes.getStringArray("rollbackForClassName");for (String rbRule : rbfc) {RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);rollBackRules.add(rule);}Class[] nrbf = attributes.getClassArray("noRollbackFor");for (Class rbRule : nrbf) {NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);rollBackRules.add(rule);}String[] nrbfc = attributes.getStringArray("noRollbackForClassName");for (String rbRule : nrbfc) {NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);rollBackRules.add(rule);}rbta.getRollbackRules().addAll(rollBackRules);return rbta;
}

创建事务代理

这里写图片描述

重要类/接口介绍

public interface PlatformTransactionManager {TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;void commit(TransactionStatus status) throws TransactionException;void rollback(TransactionStatus status) throws TransactionException;}

():返回一个已经激活的事务或创建一个新的事务(根据给定的n类型参数定义的事务属性),返回的是对象代表了当前事务的状态,其中该方法抛出(未检查异常)表示事务由于某种原因失败。

():用于提交参数代表的事务

():用于回滚参数代表的事务

(持有一系列事务相关的对象)

public abstract class TransactionSynchronizationManager {private static final ThreadLocal> resources =new NamedThreadLocal>("Transactional resources");private static final ThreadLocal> synchronizations =new NamedThreadLocal>("Transaction synchronizations");private static final ThreadLocal currentTransactionName =new NamedThreadLocal("Current transaction name");private static final ThreadLocal currentTransactionReadOnly =new NamedThreadLocal("Current transaction read-only status");private static final ThreadLocal currentTransactionIsolationLevel =new NamedThreadLocal("Current transaction isolation level");private static final ThreadLocal actualTransactionActive =new NamedThreadLocal("Actual transaction active");
}

(获取当前线程绑定的连接)

public static Object getResource(Object key) {Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);Object value = doGetResource(actualKey);if (value != null && logger.isTraceEnabled()) {logger.trace("Retrieved value [" + value + "] for key [" + actualKey + "] bound to thread [" +Thread.currentThread().getName() + "]");}return value;
}

private static Object doGetResource(Object actualKey) {Map map = resources.get();if (map == null) {return null;}Object value = map.get(actualKey);// Transparently remove ResourceHolder that was marked as void...if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {map.remove(actualKey);// Remove entire ThreadLocal if empty...if (map.isEmpty()) {resources.remove();}value = null;}return value;
}

(将新连接绑定到当前线程)

public static void bindResource(Object key, Object value) throws IllegalStateException {Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);Assert.notNull(value, "Value must not be null");Map map = resources.get();// set ThreadLocal Map if none foundif (map == null) {map = new HashMap();resources.set(map);}Object oldValue = map.put(actualKey, value);// Transparently suppress a ResourceHolder that was marked as void...if (oldValue instanceof ResourceHolder && ((ResourceHolder) oldValue).isVoid()) {oldValue = null;}if (oldValue != null) {throw new IllegalStateException("Already value [" + oldValue + "] for key [" +actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]");}if (logger.isTraceEnabled()) {logger.trace("Bound value [" + value + "] for key [" + actualKey + "] to thread [" +Thread.currentThread().getName() + "]");}
}

(释放当前线程绑定的连接)

public static Object unbindResource(Object key) throws IllegalStateException {Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);Object value = doUnbindResource(actualKey);if (value == null) {throw new IllegalStateException("No value for key [" + actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]");}return value;
}

(设置当前线程存在事务)

public static void setActualTransactionActive(boolean active) {actualTransactionActive.set(active ? Boolean.TRUE : null);
}

(设置当前线程对应事务的隔离级别)

public static void setCurrentTransactionIsolationLevel(Integer isolationLevel) {currentTransactionIsolationLevel.set(isolationLevel);
}

ive(当前线程对应的事务不为空)

public static boolean isSynchronizationActive() {return (synchronizations.get() != null);
}

(初始化当前线程的)

public static void initSynchronization() throws IllegalStateException {if (isSynchronizationActive()) {throw new IllegalStateException("Cannot activate transaction synchronization - already active");}logger.trace("Initializing transaction synchronization");synchronizations.set(new LinkedHashSet());
}

(清空当前线程的)

public static void clearSynchronization() throws IllegalStateException {if (!isSynchronizationActive()) {throw new IllegalStateException("Cannot deactivate transaction synchronization - not active");}logger.trace("Clearing transaction synchronization");synchronizations.remove();
}

(事务状态)

public interface TransactionStatus extends SavepointManager, Flushable {boolean isNewTransaction();boolean hasSavepoint();void setRollbackOnly();boolean isRollbackOnly();@Overridevoid flush();boolean isCompleted();}

atus是其实现类

(是否是新事务)

public boolean isNewTransaction() {return (hasTransaction() && this.newTransaction);
}

(是否有事务)

public boolean hasTransaction() {return (this.transaction != null);
}

(是否是只读事务)

public boolean isReadOnly() {return this.readOnly;
}

(是否是-only)

public boolean isGlobalRollbackOnly() {return ((this.transaction instanceof SmartTransactionObject) &&((SmartTransactionObject) this.transaction).isRollbackOnly());
}

与AOP的衔接

.(执行拦截器链的方法)

其中调用了.()拦截器方法。

对于标记了@的方法而言,会被代理,增强事务功能。

这些方法的增强中包括了or

(isor对应的bean)。

or支撑着整个事务功能的架构,它继承了。

public Object proceed() throws Throwable {
// 执行完所有增强后,执行切点方法(method.invoke())// 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);}
}

or.(事务增强)

public Object invoke(final 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.Class targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);// Adapt to TransactionAspectSupport's invokeWithinTransaction...return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {@Overridepublic Object proceedWithInvocation() throws Throwable {return invocation.proceed();}});
}

port.ion

逻辑:

1)获取事务属性

2)加载配置中的

3)不同的事务处理方式使用不同的逻辑。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了