js 网站头部固定,前端开发简历,上海有多少家网站建设公司,impreza wordpress前言
对于数据库的操作#xff0c;可能存在脏读、不可重复读、幻读等问题#xff0c;从而引入了事务的概念。
事务
1.1 事务的定义
事务是指在数据库管理系统中#xff0c;一系列紧密相关的操作序列#xff0c;这些操作作为一个单一的工作单元执行。事务的特点是要么全…前言
对于数据库的操作可能存在脏读、不可重复读、幻读等问题从而引入了事务的概念。
事务
1.1 事务的定义
事务是指在数据库管理系统中一系列紧密相关的操作序列这些操作作为一个单一的工作单元执行。事务的特点是要么全部成功要么全部失败不会出现部分完成的情况。如果事务中的任何一个操作失败那么整个事务都会被回滚到开始之前的状态以确保数据库的一致性和完整性。
1.2 事务的特性
事务具有4个特性原子性、一致性、隔离性和持久性。通常称为ACID。
1原子性Atomicity
事务是一个不可分割的工作单位事务中包含的所有操作要么全部成功要么全部失败。
2隔离性Isolation
一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的。
3持久性Durability
一旦事务提交成功则其所做的修改就会永久保存在数据库中即使发生系统故障也不会丢失。
4一致性Consistency
事务必须确保数据库从一个一致性状态转变到另一个一致性状态。
更准确的说事务是通过原子性、隔离性和持久性实现了事务的一致性。另外一致性还需要额外的工作来保证如转账从A转给BA的资金减少了B的资金增加了。转账要么成功、要么失败但不管成功还是失败事务的一致性要求两人的资金之和必须一致要么成功A减少了、B增加了要么失败A和B的资金都不变。为了一致性需要程序来开启事务同时修改A和B的资金从而才能保证一致性。
SpringBoot自动装载
在SpringBoot框架中会自动引入TransactionAutoConfiguration。且在META-INF的spring-autoconfigure-metadata.properties有如下配置
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration$EnableTransactionManagementConfiguration
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration$EnableTransactionManagementConfiguration.ConditionalOnBeanorg.springframework.transaction.TransactionManager说明在自动引入TransactionAutoConfiguration时必须存在TransactionManager的bean且要先引入内部类EnableTransactionManagementConfiguration。
EnableTransactionManagementConfiguration
内部类EnableTransactionManagementConfiguration的源码如下
public class TransactionAutoConfiguration {Configuration(proxyBeanMethods false)ConditionalOnBean(TransactionManager.class)ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)public static class EnableTransactionManagementConfiguration {Configuration(proxyBeanMethods false)EnableTransactionManagement(proxyTargetClass false)ConditionalOnProperty(prefix spring.aop, name proxy-target-class, havingValue false)public static class JdkDynamicAutoProxyConfiguration {}Configuration(proxyBeanMethods false)EnableTransactionManagement(proxyTargetClass true)ConditionalOnProperty(prefix spring.aop, name proxy-target-class, havingValue true,matchIfMissing true)public static class CglibAutoProxyConfiguration {}}
}
EnableTransactionManagementConfiguration内中会自动引入JdkDynamicAutoProxyConfiguration和CglibAutoProxyConfiguration且添加了EnableTransactionManagement注解。该注解会自动引入TransactionManagementConfigurationSelector。TransactionManagementConfigurationSelector的父类实现了ImportSelector接口该类的selectImports()方法返回AutoProxyRegistrar和ProxyTransactionManagementConfiguration类名数组即AutoProxyRegistrar和ProxyTransactionManagementConfiguration会自动注入到Spring IOC容器中。 Spring的配置类解析的时候会执行ConfigurationClassParser.processImports(ConfigurationClass configClass, SourceClass currentSourceClass, CollectionSourceClass importCandidates, boolean checkForCircularImports)在该方法中判断importCandidates是否继承于ImportSelector接口如果是调用ImportSelector的selectImports()方法获取需要额外自动加入容器的类。 ProxyTransactionManagementConfiguration
ProxyTransactionManagementConfiguration的源码如下
package org.springframework.transaction.annotation;/*** Transaction事务管理代理的配置类*/
Configuration
Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {/*** 返回一个BeanFactoryTransactionAttributeSourceAdvisor【继承AbstractBeanFactoryPointcutAdvisor重* 写了getPointcut()方法。即当前Advisor包含了事务需要的advice以及pointcut】* return*/Bean(name TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)Role(BeanDefinition.ROLE_INFRASTRUCTURE)public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {// 声明一个BeanFactoryTransactionAttributeSourceAdvisor对象// 传入的transactionAttributeSource为AnnotationTransactionAttributeSourceBeanFactoryTransactionAttributeSourceAdvisor advisor new BeanFactoryTransactionAttributeSourceAdvisor();advisor.setTransactionAttributeSource(transactionAttributeSource());advisor.setAdvice(transactionInterceptor());if (this.enableTx ! null) {advisor.setOrder(this.enableTx.IntegergetNumber(order));}return advisor;}/*** 创建一个AnnotationTransactionAttributeSource对象该继承AbstractFallbackTransactionAttributeSource* 对外提供了getTransactionAttribute()方法。该方法返回某个方法的事务注解信息*/BeanRole(BeanDefinition.ROLE_INFRASTRUCTURE)public TransactionAttributeSource transactionAttributeSource() {return new AnnotationTransactionAttributeSource();}/*** 创建一个TransactionInterceptor对象* return*/BeanRole(BeanDefinition.ROLE_INFRASTRUCTURE)public TransactionInterceptor transactionInterceptor() {TransactionInterceptor interceptor new TransactionInterceptor();interceptor.setTransactionAttributeSource(transactionAttributeSource());if (this.txManager ! null) {interceptor.setTransactionManager(this.txManager);}return interceptor;}}
在ProxyTransactionManagementConfiguration中自动注入了BeanFactoryTransactionAttributeSourceAdvisor、AnnotationTransactionAttributeSource和TransactionInterceptor。添加了事务处理的advisor该advisor生效时会执行TransactionInterceptor拦截器。
BeanFactoryTransactionAttributeSourceAdvisor
BeanFactoryTransactionAttributeSourceAdvisor的源码如下
package org.springframework.transaction.interceptor;/*** 继承AbstractBeanFactoryPointcutAdvisor重写了getPointcut()方法。即当前Advisor包含了事务需要的advice以及pointcut* 1、维护TransactionAttributeSource对象* 2、创建一个TransactionAttributeSourcePointcut重写getTransactionAttributeSource()返回TransactionAttributeSource对* 象给TransactionAttributeSourcePointcut进行方法事务注解判断*/
SuppressWarnings(serial)
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {// 在ProxyTransactionManagementConfiguration类中的transactionAdvisor()方法// 设置transactionAttributeSource为AnnotationTransactionAttributeSourceNullableprivate TransactionAttributeSource transactionAttributeSource;private final TransactionAttributeSourcePointcut pointcut new TransactionAttributeSourcePointcut() {OverrideNullableprotected TransactionAttributeSource getTransactionAttributeSource() {return transactionAttributeSource;}};public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {this.transactionAttributeSource transactionAttributeSource;}public void setClassFilter(ClassFilter classFilter) {this.pointcut.setClassFilter(classFilter);}Overridepublic Pointcut getPointcut() {return this.pointcut;}}
在BeanFactoryTransactionAttributeSourceAdvisor切面中切点为自定义的实现抽象类TransactionAttributeSourcePointcut的对象抽象方法getTransactionAttributeSource()返回的TransactionAttributeSource对象为ProxyTransactionManagementConfiguration的transactionAdvisor()方法传入的AnnotationTransactionAttributeSource对象。
TransactionAttributeSourcePointcut
TransactionAttributeSourcePointcut的源码如下
package org.springframework.transaction.interceptor;/*** 抽象类继承StaticMethodMatcherPointcut属于静态的方法匹配。在方法匹配中通过抽象方法getTransactionAttributeSource()获* 取TransactionAttributeSource对象然后执行TransactionAttributeSource.getTransactionAttribute()判断方法是否有事务注解* 如果有表示匹配没有则不匹配*/
SuppressWarnings(serial)
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {Overridepublic boolean matches(Method method, Nullable Class? targetClass) {if (targetClass ! null TransactionalProxy.class.isAssignableFrom(targetClass)) {return false;}// 返回AnnotationTransactionAttributeSourceTransactionAttributeSource tas getTransactionAttributeSource();// 在AnnotationTransactionAttributeSource的getTransactionAttribute()方法中// 获取方法添加的Transactional注解的信息如果没有添加Transactional注解返回nullreturn (tas null || tas.getTransactionAttribute(method, targetClass) ! null);}Overridepublic boolean equals(Object other) {if (this other) {return true;}if (!(other instanceof TransactionAttributeSourcePointcut)) {return false;}TransactionAttributeSourcePointcut otherPc (TransactionAttributeSourcePointcut) other;return ObjectUtils.nullSafeEquals(getTransactionAttributeSource(), otherPc.getTransactionAttributeSource());}Overridepublic int hashCode() {return TransactionAttributeSourcePointcut.class.hashCode();}Overridepublic String toString() {return getClass().getName() : getTransactionAttributeSource();}/*** 抽象方法获得一个TransactionAttributeSource对象* return*/Nullableprotected abstract TransactionAttributeSource getTransactionAttributeSource();}
TransactionAttributeSourcePointcut继承StaticMethodMatcherPointcutStaticMethodMatcherPointcut的类匹配默认为ClassFilter.TRUE即匹配所有的类。
当Spring中的bean对象声明之后都会调用BeanFactoryTransactionAttributeSourceAdvisor切面遍历bean的方法执行切点的matches(Method method, Nullable Class? targetClass)方法该方法执行如下
6.1调用getTransactionAttributeSource()获取一个TransactionAttributeSource。此处为AnnotationTransactionAttributeSource对象
6.2因为TransactionAttributeSource对象不为空所以执行TransactionAttributeSource的getTransactionAttribute()方法该方法会执行AnnotationTransactionAttributeSource的父类AbstractFallbackTransactionAttributeSource的getTransactionAttribute()方法如果方法有返回值则matches()方法返回true。对应的bean创建代理类并添加Advisor中的拦截器即添加TransactionInterceptor 在该方法中最终会调用子类AnnotationTransactionAttributeSource的determineTransactionAttribute()方法遍历事务的解析器从解析器中获取事务属性信息结合1中的描述会解析org.springframework.transaction.annotation包和javax.transaction包下的Transactional注解。如果没有Transactional注解getTransactionAttribute()最终返回null。matches()会返回false即不支持如果有注解则返回true。对应的bean创建代理类并添加Advisor中的拦截器即添加TransactionInterceptor
AnnotationTransactionAttributeSource
AnnotationTransactionAttributeSource的相关源码如下
package org.springframework.transaction.annotation;/*** 继承AbstractFallbackTransactionAttributeSource对外提供了getTransactionAttribute()方法。该方法返回某个方法的事务注解信息* 1、添加不同类型的事务注解解析器用于解析注解信息。支撑jta、ejb和spring的事务*/
SuppressWarnings(serial)
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSourceimplements Serializable {/** 判断包中是否有javax.transaction.Transactional这个类即项目中是否有对应的包。如果有则需要添加对应的事务解析器 */private static final boolean jta12Present ClassUtils.isPresent(javax.transaction.Transactional, AnnotationTransactionAttributeSource.class.getClassLoader());/** 判断包中是否有javax.ejb.TransactionAttribute这个类即项目中是否有对应的包。如果有则需要添加对应的事务解析器 */private static final boolean ejb3Present ClassUtils.isPresent(javax.ejb.TransactionAttribute, AnnotationTransactionAttributeSource.class.getClassLoader());/** 标记是否只有public方法才可以添加事务默认为true */private final boolean publicMethodsOnly;private final SetTransactionAnnotationParser annotationParsers;public AnnotationTransactionAttributeSource() {this(true);}/*** 设置publicMethodsOnly的值并添加事务的注解解析器集合*/public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {this.publicMethodsOnly publicMethodsOnly;if (jta12Present || ejb3Present) {this.annotationParsers new LinkedHashSet(4);// 添加spring的Transactional注解解析器this.annotationParsers.add(new SpringTransactionAnnotationParser());// 根据条件添加jta和ejb3两种事务的注解解析器if (jta12Present) {this.annotationParsers.add(new JtaTransactionAnnotationParser());}if (ejb3Present) {this.annotationParsers.add(new Ejb3TransactionAnnotationParser());}}else {// 如果不支持jta和ejb3两种注解的事务则只添加spring的Transactional注解解析器this.annotationParsers Collections.singleton(new SpringTransactionAnnotationParser());}}/*** 调用determineTransactionAttribute()方法从类中查找事务注解信息*/OverrideNullableprotected TransactionAttribute findTransactionAttribute(Class? clazz) {return determineTransactionAttribute(clazz);}/*** 调用determineTransactionAttribute()方法从方法中查找事务注解信息*/OverrideNullableprotected TransactionAttribute findTransactionAttribute(Method method) {return determineTransactionAttribute(method);}/*** 确定事务属性。遍历事务解析器集合对当前element进行解析如果能够正常解析则返回对应* 的TransactionAttribute【RuleBasedTransactionAttribute对象】否则返回null*/Nullableprotected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {for (TransactionAnnotationParser annotationParser : this.annotationParsers) {TransactionAttribute attr annotationParser.parseTransactionAnnotation(element);if (attr ! null) {return attr;}}return null;}}
在AnnotationTransactionAttributeSource构造方法中会添加SpringTransactionAnnotationParser和JtaTransactionAnnotationParser事务注解解析器。
7.1 SpringTransactionAnnotationParser
SpringTransactionAnnotationParser的源码如下
package org.springframework.transaction.annotation;
/*** 实现TransactionAnnotationParser解析org.springframework.transaction.annotation.Transactional的注解信息* 返回一个RuleBasedTransactionAttribute对象*/
SuppressWarnings(serial)
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {/*** 解析Transaction注解获取一个TransactionAttribute对象*/OverrideNullablepublic TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {// 在所提供的element上方的注释层次结构中查找Transactional的第一个注释// 并将该注释的属性与注释层次结构较低级别注释中的匹配的attribute合并AnnotationAttributes attributes AnnotatedElementUtils.findMergedAnnotationAttributes(element, Transactional.class, false, false);// 解析Transactional注解返回一个RuleBasedTransactionAttribute对象if (attributes ! null) {return parseTransactionAnnotation(attributes);}else {return null;}}public TransactionAttribute parseTransactionAnnotation(Transactional ann) {return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false));}/*** 从注解属性对象中获取事务注解相关属性信息封装成RuleBasedTransactionAttribute对象*/protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {// 根据注解的信息创建一个RuleBasedTransactionAttribute对象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));// 添加回滚规则ListRollbackRuleAttribute 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;}Overridepublic boolean equals(Object other) {return (this other || other instanceof SpringTransactionAnnotationParser);}Overridepublic int hashCode() {return SpringTransactionAnnotationParser.class.hashCode();}}
SpringTransactionAnnotationParser用于解析org.springframework.transaction.annotation包下的Transactional的注解信息。
7.2 JtaTransactionAnnotationParser
JtaTransactionAnnotationParser的源码如下
package org.springframework.transaction.annotation;/*** 实现TransactionAnnotationParser用于解析javax.transaction.Transactional注解的事务属性。返回一个RuleBasedTransactionAttribute对象*/
SuppressWarnings(serial)
public class JtaTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {/*** 判断是否有javax.transaction.Transactional如果有则进行注解解析【解析传播行为回滚的异常类、不回滚的异常类设置回滚规则】* 返回一个RuleBasedTransactionAttribute对象* param element* return*/OverrideNullablepublic TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {AnnotationAttributes attributes AnnotatedElementUtils.getMergedAnnotationAttributes(element, javax.transaction.Transactional.class);if (attributes ! null) {return parseTransactionAnnotation(attributes);}else {return null;}}public TransactionAttribute parseTransactionAnnotation(javax.transaction.Transactional ann) {return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false));}protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {RuleBasedTransactionAttribute rbta new RuleBasedTransactionAttribute();// 通过注解的value设定传播行为。默认为REQUIREDrbta.setPropagationBehaviorName(RuleBasedTransactionAttribute.PREFIX_PROPAGATION attributes.getEnum(value).toString());// 根据设置的回滚的异常类添加回滚规则ListRollbackRuleAttribute rollbackRules new ArrayList();for (Class? rbRule : attributes.getClassArray(rollbackOn)) {rollbackRules.add(new RollbackRuleAttribute(rbRule));}// 根据设置的不回滚的异常类添加回滚规则定义为不回滚for (Class? rbRule : attributes.getClassArray(dontRollbackOn)) {rollbackRules.add(new NoRollbackRuleAttribute(rbRule));}rbta.setRollbackRules(rollbackRules);return rbta;}Overridepublic boolean equals(Object other) {return (this other || other instanceof JtaTransactionAnnotationParser);}Overridepublic int hashCode() {return JtaTransactionAnnotationParser.class.hashCode();}}
JtaTransactionAnnotationParser用于解析javax.transaction包下的Transactional注解。 在6.2中调用AnnotationTransactionAttributeSource的getTransactionAttribute()最终会调用AnnotationTransactionAttributeSource的determineTransactionAttribute()方法遍历事务注解的解析器从解析器中获取事务属性信息。只要方法中添加了org.springframework.transaction.annotation包或javax.transaction包的Transactional注解则能够正常获取事务属性信息。 小结
限于篇幅本篇先分享到这里。以下做一个小结
1在SpringBoot框架的项目项目启动时会自动开启EnableTransactionManagement注解从而自动添加BeanFactoryTransactionAttributeSourceAdvisor切面添加TransactionAttributeSourcePointcut切点。该切点的ClassFilter为ClassFilter.TRUE即过滤所有的类。
2Spring的bean自动注入时会执行BeanFactoryTransactionAttributeSourceAdvisor切面遍历bena的方法执行TransactionAttributeSourcePointcut的matches()。在该方法中会执行AnnotationTransactionAttributeSource的getTransactionAttribute()方法判断方法是否添加了org.springframework.transaction.annotation包或javax.transaction包下的Transactional注解如果有则bean的代理类中添加TransactionInterceptor拦截器 关于本篇内容你有什么自己的想法或独到见解欢迎在评论区一起交流探讨下吧。