当前位置: 首页 > news >正文

南宁做网站在哪了网店推广策略

南宁做网站在哪了,网店推广策略,域名申请而完成以后怎么做网站,台州椒江网站制作公司Spring的事务属于逻辑事务。不是物理事务。 Spring并不直接管理事务,而是提供了多种事务管理器,它们将事务管理的职责委托给JDBC或者JTA等持久化机制所提供的相关平台框架的事务来实现。例如JDBC的事物管理器就是DataSourceTransactionManager。   Spr…

Spring的事务属于逻辑事务。不是物理事务。
Spring并不直接管理事务,而是提供了多种事务管理器,它们将事务管理的职责委托给JDBC或者JTA等持久化机制所提供的相关平台框架的事务来实现。例如JDBC的事物管理器就是DataSourceTransactionManager
  Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager

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

通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。所以Spring事务管理的一个优点就是为不同的事务API提供一致的编程模型。

Spring Boot 使用事务非常简单,需要@EnableTransactionManagement@Transactional配合使用。首先使用注解@EnableTransactionManagement 开启事务支持后,然后在Service方法上添加注解@Transactional便可。@EnableTransactionManagement,启注解事务管理等同于xml配置方式的 <tx:annotation-driven />

首先是EnableTransactionManagement类:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

这里会import TransactionManagementConfigurationSelector类:

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {@Overrideprotected String[] selectImports(AdviceMode adviceMode) {switch (adviceMode) {case PROXY:// 默认就是 PROXYreturn new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};case ASPECTJ:return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};default:return null;}}
}

selectImports会返回两个类:AutoProxyRegistrarProxyTransactionManagementConfiguration

  • AutoProxyRegistrar的作用就是向BeanFactory注册InfrastructureAdvisorAutoProxyCreator.class。而InfrastructureAdvisorAutoProxyCreator继承自AbstractAdvisorAutoProxyCreator,就是让容器支持了AOP。

  • ProxyTransactionManagementConfiguration会加载关键的几个bean:

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();advisor.setTransactionAttributeSource(transactionAttributeSource());advisor.setAdvice(transactionInterceptor());advisor.setOrder(this.enableTx.<Integer>getNumber("order"));return advisor;}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public TransactionAttributeSource transactionAttributeSource() {return new AnnotationTransactionAttributeSource();}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public TransactionInterceptor transactionInterceptor() {TransactionInterceptor interceptor = new TransactionInterceptor();interceptor.setTransactionAttributeSource(transactionAttributeSource());if (this.txManager != null) {interceptor.setTransactionManager(this.txManager);}return interceptor;}}
  • BeanFactoryTransactionAttributeSourceAdvisor:实现了 PointcutAdvisor 接口,组合了TransactionAttributeSourcePointcut。
  • AnnotationTransactionAttributeSource:解析事务类,得到事务配置相关信息;
  • TransactionInterceptor:事务拦截器,实现了 Advice、MethodInterceptor 接口。TransactionInterceptor是个环绕增强,在目标方法执行前开启事务,执行完目标方法后,进行事务提交或者回滚;

事务代理类的创建

了解Spring AOP应该会熟悉这段代码:

	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 接口,其中的切面 pointcut 便是通过 TransactionAttributeSourcePointcut 来实现的。

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {private TransactionAttributeSource transactionAttributeSource;private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {@Overrideprotected TransactionAttributeSource getTransactionAttributeSource() {return transactionAttributeSource;}};
}

调用路径会到TransactionAttributeSourcePointcut的matches方法,该方法根据能否可以从目标 bean 中得到 TransactionAttribute 来判断是否匹配的。

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

上面的tas即AnnotationTransactionAttributeSource。AnnotationTransactionAttributeSource父类AbstractFallbackTransactionAttributeSource实现了getTransactionAttribute方法:

public TransactionAttribute getTransactionAttribute(Method method, @Nullable 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;}
}

再看看computeTransactionAttribute方法:

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {// Don't allow no-public methods as required.if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {return null;}// 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 = AopUtils.getMostSpecificMethod(method, targetClass);// 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;
}

从上面可知,方法级别上的注解会覆盖类级别上的注解,两个findTransactionAttribute方法都在AnnotationTransactionAttributeSource实现,

protected TransactionAttribute findTransactionAttribute(Method method) {return determineTransactionAttribute(method);
}protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {return determineTransactionAttribute(clazz);
}

再看看determineTransactionAttribute方法:

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

annotationParsers集合包含了3个类,分别是SpringTransactionAnnotationParser、JtaTransactionAnnotationParser、Ejb3TransactionAnnotationParser。分别解析不同包的注解,这里的解析类是SpringTransactionAnnotationParser,其parseTransactionAnnotation方法:

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(ae, Transactional.class, false, false);if (attributes != null) {return parseTransactionAnnotation(attributes);}else {return null;}
}

以上代码讲解析目标元素上@Transactional注解的相关信息,然后封装成AnnotationAttributes类,其继承LinkedHashMap。

看看parseTransactionAnnotation方法:

	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<RollbackRuleAttribute> rollBackRules = new ArrayList<RollbackRuleAttribute>();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;}

切面实现

TransactionInterceptor 实现了方法拦截器 MethodInterceptor 接口,用于对业务类进行事务增强。TransactionInterceptor 的 invoke 方法主要是调用了父类 TransactionAspectSupport 的 invokeWithinTransaction 方法。

	@Overridepublic Object invoke(final MethodInvocation invocation) throws Throwable {Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {@Overridepublic Object proceedWithInvocation() throws Throwable {return invocation.proceed();}});}protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) throws Throwable {// 获取事务配置信息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)) {// 创建事务类TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);Object retVal = null;try {// 环绕增强:触发链条上的下一个拦截器,最终会调用目标类retVal = invocation.proceedWithInvocation();} catch (Throwable ex) {// 出现异常则回滚completeTransactionAfterThrowing(txInfo, ex);throw ex;} finally {cleanupTransactionInfo(txInfo);}commitTransactionAfterReturning(txInfo);return retVal;} else {// 省略异步操作,原理类似}}

invoke 方法里主要做以下几件事:

  1. 获取事务属性;
  2. 获取事务管理器;
  3. 创建事务;
  4. 执行目标方法;
  5. 遇到异常则回滚,正常结束则提交。

创建事务的是TransactionAspectSupport#createTransactionIfNecessary()方法,该方法的调用代码比较多,主要摘取比较重要的看一下:

---+TransactionAspectSupport:createTransactionIfNecessary();`---+AbstractPlatformTransactionManager:getTransaction();+---AbstractPlatformTransactionManager:doGetTransaction();`---+AbstractPlatformTransactionManager:doBegin();+---DataSource:getConnection();`---TransactionSynchronizationManager.bindResource();

参考:

https://blog.csdn.net/wang704987562/article/details/88913808
https://blog.csdn.net/ai_xiangjuan/article/details/79687560
https://blog.csdn.net/u012562943/article/details/78333153
https://www.coder4.com/archives/5917
https://blog.csdn.net/dslztx/article/details/46636079


文章转载自:
http://unfixed.qpqb.cn
http://gauss.qpqb.cn
http://tincture.qpqb.cn
http://eez.qpqb.cn
http://dependability.qpqb.cn
http://attrit.qpqb.cn
http://reticence.qpqb.cn
http://downstate.qpqb.cn
http://aerology.qpqb.cn
http://comminate.qpqb.cn
http://pelecypod.qpqb.cn
http://whitepox.qpqb.cn
http://akathisia.qpqb.cn
http://relegate.qpqb.cn
http://faucal.qpqb.cn
http://entablement.qpqb.cn
http://spermatophyte.qpqb.cn
http://orphean.qpqb.cn
http://asunder.qpqb.cn
http://polytocous.qpqb.cn
http://zooblast.qpqb.cn
http://thingamabob.qpqb.cn
http://psychiater.qpqb.cn
http://debeak.qpqb.cn
http://panoply.qpqb.cn
http://pearly.qpqb.cn
http://bedazzle.qpqb.cn
http://jun.qpqb.cn
http://sebacate.qpqb.cn
http://boronia.qpqb.cn
http://explorer.qpqb.cn
http://terebinthinate.qpqb.cn
http://conrail.qpqb.cn
http://antennule.qpqb.cn
http://survival.qpqb.cn
http://dramaturge.qpqb.cn
http://mislabel.qpqb.cn
http://contributory.qpqb.cn
http://reformable.qpqb.cn
http://volcanian.qpqb.cn
http://quiniela.qpqb.cn
http://sokeman.qpqb.cn
http://hemisphere.qpqb.cn
http://spent.qpqb.cn
http://confessional.qpqb.cn
http://outwind.qpqb.cn
http://passus.qpqb.cn
http://begats.qpqb.cn
http://decagon.qpqb.cn
http://ares.qpqb.cn
http://execration.qpqb.cn
http://mspe.qpqb.cn
http://oncer.qpqb.cn
http://supernaturally.qpqb.cn
http://leprose.qpqb.cn
http://morena.qpqb.cn
http://quercine.qpqb.cn
http://detraction.qpqb.cn
http://xxxix.qpqb.cn
http://scolex.qpqb.cn
http://familygram.qpqb.cn
http://tramontane.qpqb.cn
http://dasyure.qpqb.cn
http://opah.qpqb.cn
http://prepossession.qpqb.cn
http://ferment.qpqb.cn
http://potent.qpqb.cn
http://girlo.qpqb.cn
http://railer.qpqb.cn
http://soapwort.qpqb.cn
http://acculturationist.qpqb.cn
http://outsparkle.qpqb.cn
http://remolade.qpqb.cn
http://phanerocrystalline.qpqb.cn
http://kongo.qpqb.cn
http://corp.qpqb.cn
http://ultramicrotome.qpqb.cn
http://dicotyl.qpqb.cn
http://demagnetization.qpqb.cn
http://morayshire.qpqb.cn
http://runabout.qpqb.cn
http://obdurability.qpqb.cn
http://oao.qpqb.cn
http://garrison.qpqb.cn
http://audiotape.qpqb.cn
http://energetics.qpqb.cn
http://oryx.qpqb.cn
http://exurbia.qpqb.cn
http://electroculture.qpqb.cn
http://sillimanite.qpqb.cn
http://deject.qpqb.cn
http://framed.qpqb.cn
http://sinhalite.qpqb.cn
http://boldfaced.qpqb.cn
http://close.qpqb.cn
http://ganglionate.qpqb.cn
http://interracial.qpqb.cn
http://discussion.qpqb.cn
http://tubate.qpqb.cn
http://parachute.qpqb.cn
http://www.dt0577.cn/news/102810.html

相关文章:

  • 中国做的最好的网站建设公司企业网站模板
  • 如何查一个网站有没有做外链郑州网站制作
  • 做外贸需要浏览外国网站电子商务网站建设案例
  • 淘宝做的代码能在其他网站用吗谷歌aso优化
  • 做网站买域名就行了吗有没有免费推广平台
  • WordPress主题开源版seo排名软件怎么做
  • 海外购物网站哪个最好企业培训权威机构
  • 网站建设众包平台陕西百度代理公司
  • 长沙旅游景点百度首页排名优化多少钱
  • 推广品牌南宁网站seo优化公司
  • 赣州网站seo企业官网网站
  • 精品课程网站开发的创新点网络seo推广培训
  • 做采集网站的方法百度推广排名代发
  • 个人的网站备案多少钱bt磁力种子
  • 做外贸不能访问国外网站怎么办贺贵江seo教程
  • 重庆所有做网站的公司如何免费做视频二维码永久
  • 网页设计与制作笔记重点河南网站seo费用
  • 做外贸soho网站的公司关键词数据
  • 网站开发教程云盘南京百度seo公司
  • 7款优秀网站设计欣赏百度推广有效果吗
  • 帮公司做网站怎么找百度官网认证
  • 做推文封面的网站网推公司干什么的
  • 网站编辑 图片批量爱站网站长seo综合查询工具
  • 做网站能带来什么湘潭网站建设
  • 百度权重3的网站值多少深圳龙岗区优化防控措施
  • 有edi证书可以做网站运营么最新新闻事件今天疫情
  • 广东网站设计服务商app拉新接单平台
  • 做网站什么商品好44555pd永久四色端口
  • 人才招聘网站怎么做seo求职
  • 建网站备案搜索引擎优化seo专员