CREATEDATABASE testgeli CHARACTERSET utf8;USE testgeli;CREATETABLE test(
id INT(11)PRIMARYKEY,
NAME VARCHAR(20),
pass VARCHAR(20),
url VARCHAR(20));INSERTINTO test VALUES(1,'张三','123','com.qi');INSERTINTO test VALUES(2,'李四','123','com.qi');INSERTINTO test VALUES(3,'王五','123','com.qi');INSERTINTO test VALUES(4,'赵六','123','com.qi');
publicclassTransactionManagementConfigurationSelectorextendsAdviceModeImportSelector<EnableTransactionManagement>{//一般他最终会操作的,被@Import导入的会变成bean,他通常返回一些全限定名称来操作对应的bean@OverrideprotectedString[]selectImports(AdviceMode adviceMode){switch(adviceMode){case PROXY://两个重要的组件,即AutoProxyRegistrar和ProxyTransactionManagementConfigurationreturnnewString[]{AutoProxyRegistrar.class.getName(),ProxyTransactionManagementConfiguration.class.getName()};case ASPECTJ:returnnewString[]{determineTransactionAspectClass()};default:returnnull;}}//..}//进入AutoProxyRegistrar(加载事务控制组件)publicclassAutoProxyRegistrarimplementsImportBeanDefinitionRegistrar{privatefinalLog logger =LogFactory.getLog(getClass());/**
* Register, escalate, and configure the standard auto proxy creator (APC) against the
* given registry. Works by finding the nearest annotation declared on the importing
* {@code @Configuration} class that has both {@code mode} and {@code proxyTargetClass}
* attributes. If {@code mode} is set to {@code PROXY}, the APC is registered; if
* {@code proxyTargetClass} is set to {@code true}, then the APC is forced to use
* subclass (CGLIB) proxying.
* <p>Several {@code @Enable*} annotations expose both {@code mode} and
* {@code proxyTargetClass} attributes. It is important to note that most of these
* capabilities end up sharing a {@linkplain AopConfigUtils#AUTO_PROXY_CREATOR_BEAN_NAME
* single APC}. For this reason, this implementation doesn't "care" exactly which
* annotation it finds -- as long as it exposes the right {@code mode} and
* {@code proxyTargetClass} attributes, the APC can be registered and configured all
* the same.
*/@OverridepublicvoidregisterBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry){boolean candidateFound =false;Set<String> annTypes = importingClassMetadata.getAnnotationTypes();for(String annType : annTypes){AnnotationAttributes candidate =AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);if(candidate ==null){continue;}Object mode = candidate.get("mode");Object proxyTargetClass = candidate.get("proxyTargetClass");if(mode !=null&& proxyTargetClass !=null&&AdviceMode.class== mode.getClass()&&Boolean.class== proxyTargetClass.getClass()){//到这里
candidateFound =true;if(mode ==AdviceMode.PROXY){//我们进入这里AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);if((Boolean) proxyTargetClass){AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);return;}}}}if(!candidateFound && logger.isInfoEnabled()){String name =getClass().getSimpleName();
logger.info(String.format("%s was imported but no annotations were found "+"having both 'mode' and 'proxyTargetClass' attributes of type "+"AdviceMode and boolean respectively. This means that auto proxy "+"creator registration and configuration may not have occurred as "+"intended, and components may not be proxied as expected. Check to "+"ensure that %s has been @Import'ed on the same class where these "+"annotations are declared; otherwise remove the import of %s "+"altogether.", name, name, name));}}}publicabstractclassAopConfigUtils{//..//到这里@NullablepublicstaticBeanDefinitionregisterAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry){returnregisterAutoProxyCreatorIfNecessary(registry,null);}@NullablepublicstaticBeanDefinitionregisterAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,@NullableObject source){//我们看看InfrastructureAdvisorAutoProxyCreator类:/*
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
你全局搜索一下AbstractAutoProxyCreator,看看与后置通知有什么联系呢,自己全局搜索看看就知道了
*/returnregisterOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);}//..@NullableprivatestaticBeanDefinitionregisterOrEscalateApcAsRequired(Class<?> cls,BeanDefinitionRegistry registry,@NullableObject source){Assert.notNull(registry,"BeanDefinitionRegistry must not be null");if(registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)){BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);if(!cls.getName().equals(apcDefinition.getBeanClassName())){int currentPriority =findPriorityForClass(apcDefinition.getBeanClassName());int requiredPriority =findPriorityForClass(cls);if(currentPriority < requiredPriority){
apcDefinition.setBeanClassName(cls.getName());}}returnnull;}RootBeanDefinition beanDefinition =newRootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order",Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);return beanDefinition;}//..}//我们进入ProxyTransactionManagementConfiguration@Configuration@Role(BeanDefinition.ROLE_INFRASTRUCTURE)publicclassProxyTransactionManagementConfigurationextendsAbstractTransactionManagementConfiguration{@Bean(name =TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)publicBeanFactoryTransactionAttributeSourceAdvisortransactionAdvisor(){//事务增强器BeanFactoryTransactionAttributeSourceAdvisor advisor =newBeanFactoryTransactionAttributeSourceAdvisor();//向事务增强器中注入属性解析器transactionAttributeSource
advisor.setTransactionAttributeSource(transactionAttributeSource());//向事务增强器中注入事务拦截器transactionInterceptor
advisor.setAdvice(transactionInterceptor());if(this.enableTx !=null){
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));}return advisor;}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)publicTransactionAttributeSourcetransactionAttributeSource(){//我们来看看属性解析器returnnewAnnotationTransactionAttributeSource();}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)publicTransactionInterceptortransactionInterceptor(){//我们来看看事务拦截器TransactionInterceptor interceptor =newTransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());if(this.txManager !=null){
interceptor.setTransactionManager(this.txManager);}return interceptor;}}
事务拦截器:TransactionInterceptor interceptor = new TransactionInterceptor();
publicclassTransactionInterceptorextendsTransactionAspectSupportimplementsMethodInterceptor,Serializable{//其中,他实现的MethodInterceptor接口是否与cglib对应的那个参数一样呢(并不一样,所以这里是invoke),且可以在前面看到:/*
//把增强和通用拦截器(MethodInterceptor)对象合并,都适配成Advisor(具体怎么得到和生成,这里就不说明了,具体可以百度)
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
当然,有很多方法会操作,这里只是给出主要的,一般都是与xml类似操作的,只是读取方式不同,这里给出主要的操作(主要的扫描,到配置,都没有说明)
*///.. @Override@NullablepublicObjectinvoke(MethodInvocation invocation)throwsThrowable{// 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...//会触发原有业务逻辑调用,在调用时会增强事务(即对应的找到方法操作就在这里,当然,可能有其他操作使得确定的,这里了解即可),这样在属性解析后,我们进行增强,现在我们进入returninvokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);}//..}publicabstractclassTransactionAspectSupportimplementsBeanFactoryAware,InitializingBean{//..@NullableprotectedObjectinvokeWithinTransaction(Method method,@NullableClass<?> targetClass,finalInvocationCallback invocation)throwsThrowable{// If the transaction attribute is null, the method is non-transactional.//获取属性解析器TransactionAttributeSource tas =getTransactionAttributeSource();finalTransactionAttribute txAttr =(tas !=null? tas.getTransactionAttribute(method, targetClass):null);//获取事务管理器,现在事务有了,属性有了,那么就能增强了finalPlatformTransactionManager tm =determineTransactionManager(txAttr);finalString joinpointIdentification =methodIdentification(method, targetClass, txAttr);if(txAttr ==null||!(tm instanceofCallbackPreferringPlatformTransactionManager)){// Standard transaction demarcation with getTransaction and commit/rollback calls.//开启(创建)事务TransactionInfo txInfo =createTransactionIfNecessary(tm, txAttr, joinpointIdentification);Object retVal;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{Object result;finalThrowableHolder throwableHolder =newThrowableHolder();// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.try{
result =((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, 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 instanceofRuntimeException){throw(RuntimeException) ex;}else{thrownewThrowableHolderException(ex);}}else{// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;returnnull;}}finally{cleanupTransactionInfo(txInfo);}});}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;}// Check result state: It might indicate a Throwable to rethrow.if(throwableHolder.throwable !=null){throw throwableHolder.throwable;}return result;}}//..}
MySQL InnoDB 集群提供完整的高可用性 MySQL 的解决方案。通过使用MySQL Shell附带的AdminAPI,您可以轻松 配置和管理至少三个MySQL服务器的组 实例以充当 InnoDB 集群。
InnoDB 集群中的每个 MySQL 服务器实例都运行 MySQL 组复制,提供复制机制 InnoDB…