docs/Spring全家桶/Spring源码分析/Spring事务/Spring事务(二):事务的执行流程.md
spring ֮ʶһУͨһ demo ʾʹ spring ܣȻ @EnableTransactionManagement עĹܣĽ spring ش롣
spring ǻ aop ģʹôһϵвĽͨԵķʽĴ̡
spring ֮ʶͨ @EnableTransactionManagement ע⣬ָע spring ע InfrastructureAdvisorAutoProxyCreator AbstractAdvisorAutoProxyCreator ࣬ɴģڽ InfrastructureAdvisorAutoProxyCreator Ĵ̡
AbstractAdvisorAutoProxyCreatorķԼɣ spring aop ֮ AnnotationAwareAspectJAutoProxyCreator ϣ spring aop ֮ AnnotationAwareAspectJAutoProxyCreator £ѾϸҪ aop вĵطҪϸ˽ spring aop βС飬Ķƪ¡
ǽ AbstractAutoProxyCreator#postProcessBeforeInitialization
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
...
if (...) {
//1\. shouldSkip:
// - AspectJAwareAdvisorAutoProxyCreator shouldSkip ᴦ @Aspect ע࣬
// е@Before/@After/@AroundעװΪAdvisorٵø(Ҳ
// AbstractAutoProxyCreator)shouldSkip
// - InfrastructureAdvisorAutoProxyCreatorֱִAbstractAutoProxyCreatorshouldSkip
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
if(...) {
...
// 2\. getAdvicesAndAdvisorsForBeanȡڵǰadvisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(
beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
...
return proxy;
}
return null;
}
ͬ㣬ѾעеIJ죬 shouldSkipûɶ˵ģصչ getAdvicesAndAdvisorsForBean(...)
BeanFactoryAdvisorRetrievalHelper#findAdvisorBeansһ· getAdvicesAndAdvisorsForBean(...) еIJ AspectJAwareAdvisorAutoProxyCreator IJ̫𣬲иΪҪǿ££
BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// ҵǰbeanFactory Advisor bean class
// AdvisorûʵAdvisorؽӿڣҲxmlָ
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
...
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
...
// advisorbean namespringлȡ bean
advisors.add(this.beanFactory.getBean(name, Advisor.class));
...
}
...
return advisors;
}
Ҫǻȡ spring е advisorʵ AnnotationAwareAspectJAutoProxyCreator ҲôȡģֻڻȡǰAnnotationAwareAspectJAutoProxyCreator shouldSkip(...) а @Aspect а @Befor/@After/@Around עķװɶӦ Advisor InfrastructureAdvisorAutoProxyCreator ᣬһʼҲᵽˡ
spring ֮ʶһУ @EnableTransactionManagement עʱǷעͨ @Bean ע spring BeanFactoryTransactionAttributeSourceAdvisor bean ͻ BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans ȡ
AopUtils#canApply(...)ŷһ·ߣžж advisor ܷĿ class ĵطˣ
/**
* жadvisorܷĿclass
*/
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
...
// жǷΪ PointcutAdvisoradvisorΪBeanFactoryTransactionAttributeSourceAdvisor
// ʵPointcutAdvisorĴִ
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
//ʹ PointcutAdvisor ж
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
...
}
/**
* жadvisorܷĿclass
*/
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
//1\. еǷų
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
// ȡƥMethodMatcher.TRUE ΪĬϵ MethodMatcher
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
return true;
}
...
// classestargetClassObjectиࡢнӿ
Set<Class<?>> classes = new LinkedHashSet<>();
// ʡԻȡtargetClassĸಽ
...
for (Class<?> clazz : classes) {
// ȡ clazz ķǰķObjectиӿڵĬϷ
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
// 2\. ƥĹؼ
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
һĴ AnnotationAwareAspectJAutoProxyCreator һģһǶǵͬķжϣڴĵ advisor ͬյõľƥҲͬ
Ӵķƥ Pointcut У Pointcut Advisorɼ Advisor ʮֹؼ Advisor Ϊ BeanFactoryTransactionAttributeSourceAdvisorǾࡣ
BeanFactoryTransactionAttributeSourceAdvisor ƥһС ڵķУ֪ж targetClass ܷӦõǰ advisor ĹԴ advisor pointcut``pointcut طжϹ
pc.getClassFilter().matches(targetClass)pc.getMethodMatcher().matches(method, targetClass)һС Ǵ BeanFactoryTransactionAttributeSourceAdvisor ֣һƥ
public class BeanFactoryTransactionAttributeSourceAdvisor
extends AbstractBeanFactoryPointcutAdvisor {
@Nullable
private TransactionAttributeSource transactionAttributeSource;
/**
* pointcut
*/
private final TransactionAttributeSourcePointcut pointcut =
new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
/**
* transactionAttributeSource
*/
public void setTransactionAttributeSource(TransactionAttributeSource
transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
}
/**
* ClassFilter
*/
public void setClassFilter(ClassFilter classFilter) {
this.pointcut.setClassFilter(classFilter);
}
/**
* ȡ pointcut
*/
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}
ĴؼѾעˣܽ£BeanFactoryTransactionAttributeSourceAdvisor#getPointcut õ pointcut Ϊ TransactionAttributeSourcePointcut private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {...} дġ
BeanFactoryTransactionAttributeSourceAdvisor transactionAttributeSource ʲôأ ProxyTransactionManagementConfiguration д transactionAdvisor Ĵ룺
public class ProxyTransactionManagementConfiguration
extends AbstractTransactionManagementConfiguration {
// ʡ
...
/**
* ȡSpring @Transactional ע⣬ӦԹSpringṹ
*/
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
/**
* ǿ.
* transactionAttributeSourcetransactionAttributeSource() صĶ
*/
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource,
TransactionInterceptor transactionInterceptor) {
BeanFactoryTransactionAttributeSourceAdvisor advisor =
new BeanFactoryTransactionAttributeSourceAdvisor();
// ࣬ @Transactional
advisor.setTransactionAttributeSource(transactionAttributeSource);
...
return advisor;
}
}
ɴ˿֪BeanFactoryTransactionAttributeSourceAdvisor transactionAttributeSource Ϊ AnnotationTransactionAttributeSource.
ٻص BeanFactoryTransactionAttributeSourceAdvisorķ֪getPointcut() õ TransactionAttributeSourcePointcut Ȼࣺ
abstract class TransactionAttributeSourcePointcut
extends StaticMethodMatcherPointcut implements Serializable {
protected TransactionAttributeSourcePointcut() {
// ڹ췽 ClassFilter
setClassFilter(new TransactionAttributeSourceClassFilter());
}
/**
* pointcut matches
*/
@Override
public boolean matches(Method method, Class<?> targetClass) {
// õĽΪAnnotationTransactionAttributeSource
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
/**
* BeanFactoryTransactionAttributeSourceAdvisor ָ
*/
@Nullable
protected abstract TransactionAttributeSource getTransactionAttributeSource();
/**
* ڲ࣬ʵ ClassFilter
*/
private class TransactionAttributeSourceClassFilter implements ClassFilter {
/**
* ClassFilter matches
*/
@Override
public boolean matches(Class<?> clazz) {
// ǷΪTransactionalProxyPlatformTransactionManagerPersistenceExceptionTranslatorʵ
if (TransactionalProxy.class.isAssignableFrom(clazz) ||
PlatformTransactionManager.class.isAssignableFrom(clazz) ||
PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
return false;
}
//ж TransactionAttributeSource ȡǷΪ
// õĽΪAnnotationTransactionAttributeSource
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.isCandidateClass(clazz));
}
}
}
ķǵõһҪĹ
pc.getClassFilter().matches(targetClass)``ClassFilter Ϊ TransactionAttributeSourceClassFilterƥĹҵˣƥ䷽Ĺأǽ TransactionAttributeSourcePointcut#getMethodMatcher() StaticMethodMatcherPointcut
public abstract class StaticMethodMatcherPointcut
extends StaticMethodMatcher implements Pointcut {
// ʡһЩ
...
@Override
public final MethodMatcher getMethodMatcher() {
return this;
}
}
صľȻ thisǸɶҪţϸ TransactionAttributeSourcePointcut̳ StaticMethodMatcherPointcut
abstract class TransactionAttributeSourcePointcut
extends StaticMethodMatcherPointcut implements Serializable {
// ʡһЩ
...
}
ԣpc.getMethodMatcher() õľ TransactionAttributeSourcePointcut mathes(...) TransactionAttributeSourcePointcut#matches.
ڱСڵܽ·Ľ
pc.getClassFilter().matches(targetClass)``ClassFilter Ϊ TransactionAttributeSourceClassFilterpc.getMethodMatcher().matches(method, targetClass)``methodMatcher Ϊ TransactionAttributeSourcePointcutTransactionAttributeSourcePointcut#getTransactionAttributeSourceصĽΪ AnnotationTransactionAttributeSource.1.2 ֣֪ǰ advisor ܷӦĿ classҪͬʱƥ
pc.getClassFilter().matches(targetClass)``ClassFilter Ϊ TransactionAttributeSourceClassFilterpc.getMethodMatcher().matches(method, targetClass)``methodMatcher Ϊ TransactionAttributeSourcePointcutTransactionAttributeSourceClassFilter#matchesжϵǰǷΪǷΪ TransactionalProxy``PlatformTransactionManager``PersistenceExceptionTranslator ʵ࣬Ȼ AnnotationTransactionAttributeSource#isCandidateClass жϣTransactionAttributeSourcePointcut#matches AnnotationTransactionAttributeSource#getTransactionAttributeڼ̳йϵʵʵõ AbstractFallbackTransactionAttributeSource#getTransactionAttributeжϡǾ¾ƥ̡
AnnotationTransactionAttributeSource#isCandidateClassֱ⣬ isCandidateClass
AnnotationTransactionAttributeSource#isCandidateClass
@Override
public boolean isCandidateClass(Class<?> targetClass) {
// ҵеannotationParsersѭƥ
for (TransactionAnnotationParser parser : this.annotationParsers) {
if (parser.isCandidateClass(targetClass)) {
return true;
}
}
return false;
}
Կѭ TransactionAnnotationParser isCandidateClass this.annotationParsers ɶأͨԣ£
this.annotationParsers ֻ SpringTransactionAnnotationParserǽ isCandidateClass
public class SpringTransactionAnnotationParser
implements TransactionAnnotationParser, Serializable {
/**
* жǷ @Transactional ע
*/
@Override
public boolean isCandidateClass(Class<?> targetClass) {
return AnnotationUtils.isCandidateClass(targetClass, Transactional.class);
}
}
յõ AnnotationUtils.isCandidateClassжָǷ @Transactional ע⡣
ǾˣTransactionAttributeSourceClassFilter#matches ųһЩ (TransactionalProxy/PlatformTransactionManager/PersistenceExceptionTranslator ) ջƥ @Transactional עࡣ
AnnotationTransactionAttributeSource#getTransactionAttributeķƥɹܱʾɹƥ䣬ƥ TransactionAttributeSourcePointcut#matchesͬʱŻƥɹTransactionAttributeSourcePointcut#matches AnnotationTransactionAttributeSource#getTransactionAttribute ƥģǸȥ
public abstract class AbstractFallbackTransactionAttributeSource
implements TransactionAttributeSource {
/**
* ȡ @Transactional ע
*/
public TransactionAttribute getTransactionAttribute(Method method,
@Nullable Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null;
}
// ʡԴӻлȡ
...
else {
// ȡ Transaction ԣ @Transactional ע
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
// ʡԷ뻺
...
return txAttr;
}
}
}
AnnotationTransactionAttributeSource getTransactionAttribute Ǽ̳ AbstractFallbackTransactionAttributeSource ģǽķ AbstractFallbackTransactionAttributeSource#getTransactionAttributeȡϵ @Transactional עԣǸ computeTransactionAttribute(...)
AbstractFallbackTransactionAttributeSource
protected TransactionAttribute computeTransactionAttribute(Method method,
@Nullable Class<?> targetClass) {
// ĬϱҪ public ֧
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// 1\. ȡȷеķ紫classIFooʵʵĵclassDefaultFoo
// ôӦý IFoo#method תΪ DefaultFoo#method
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// 2\. ӷϻȡ @Transactional
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
// 3\. ϻȡ @Transaction
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
if (specificMethod != method) {
// 4\. ȷеķҲҴķϵ
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// 5\. ϶ûҵȷеϵ
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
// 6\. ûлȡշnull
return null;
}
Ϸ̣ܽȡ @Transactional £
class IFooʵʵĵ class DefaultFooͻὫ IFoo#method תΪ DefaultFoo#method@Transactional@Transaction@Transaction@Transactionnullspring δӷϻȡ @Transactional أȥ
AnnotationTransactionAttributeSource
// ӷϻȡ @Transactional
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
// ϻȡ @Transactional
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
return determineTransactionAttribute(clazz);
}
// յõķ
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
for (TransactionAnnotationParser parser : this.annotationParsers) {
// @Transactional ע
TransactionAttribute attr = parser.parseTransactionAnnotation(element);
if (attr != null) {
return attr;
}
}
return null;
}
Ƕǵ AnnotationTransactionAttributeSource#determineTransactionAttribute ȡģ AnnotationTransactionAttributeSource#determineTransactionAttribute TransactionAnnotationParser#parseTransactionAnnotation this.annotationParsers ǰѾˣֻһࣺSpringTransactionAnnotationParserǸȥ
SpringTransactionAnnotationParser
/**
* ȡ Transactional ע⣬ null
*/
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
// ȡ Transactional ע⣬ null
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
/**
* Transactional עľ
*/
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());
// ijʱʱ
rbta.setTimeout(attributes.getNumber("timeout").intValue());
// ǷΪֻ
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
// ع쳣
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
// ع쳣
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
rbta.setRollbackRules(rollbackRules);
return rbta;
}
ԿTransactional עĸԽ RuleBasedTransactionAttribute.
ˣǾˣTransactionAttributeSourcePointcut#matches жû Transactional ע⡣
Ĵ AbstractAutoProxyCreator#postProcessAfterInitialization ɵģͬ aop һģһͲٷˣ˽Сɲ鿴 spring aop ֮ AnnotationAwareAspectJAutoProxyCreator £
ִз棬 aop ִ̲һͨ Advisor ҵӦ Adviceͨ Advice ҵӦ methodInterceptorִе MethodInterceptor#invoke MethodInterceptor Ϊ TransactionInterceptor ProxyTransactionManagementConfiguration ͨ @Bean עġ
aop ̣Dzط spring aop ֮ jdk ̬ spring aop ֮ cglib ϸȤСвģֱ TransactionInterceptor#invoke ִ̡
Ĵ TransactionInterceptor#invoke У
TransactionInterceptor#invoke
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null
? AopUtils.getTargetClass(invocation.getThis()) : null);
// ¿
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
Ĵ TransactionAspectSupport#invokeWithinTransaction У
TransactionAspectSupport#invokeWithinTransaction
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
TransactionAttributeSource tas = getTransactionAttributeSource();
// ȡ@Transactional
final TransactionAttribute txAttr = (tas != null
? tas.getTransactionAttribute(method, targetClass) : null);
// ȡIOCлȡ
final TransactionManager tm = determineTransactionManager(txAttr);
// ʡ ReactiveTransactionManager Ĵ
...
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
// ȡȫʽΪ".."
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// ĴҲǽҪĵط
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// 1\.
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// 2\. ִоҵ
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 3\. 쳣ع
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// Ϣ
cleanupTransactionInfo(txInfo);
}
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
// 4\. ύлжǷ֧
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
// ʡ
...
}
}
Ϸȫˣ£
ľǽһƪ·ֻҪĴд˽⼴ɡ
ҪдĴִ̣ʵЩͬ aop һ£ط aop ͬIJ֣
ڴĴ棬жϵǰܷʹ BeanFactoryTransactionAttributeSourceAdvisorص TransactionAttributeSourceClassFilter#matches TransactionAttributeSourcePointcut#matches жϵĺڣ
ڷִϵģԷ TransactionInterceptor#invoke ִ̣ЩĿύ쳣ع̸ƽʹõIJľϸDzûз
صĴִִ̣еľϸƪٷ
ԭӣhttps://my.oschina.net/funcy/blog/4773457 ߸ˮƽд֮ӭָԭףҵתϵȨҵתע