事务是逻辑上的一组执行单元,要么都执行,要么都不执行。
ACID是指数据库管理系统DBMS中事物所具有四个特性。
在数据库系统中,一个事务由一系列的数据库操作组成一个完整的逻辑过程,比如银行转账,从原账户扣除金额,目标账户增加金额。
2.1)PlatformTransactionManager: (平台)事务管理器
2.2)TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则
2.3)TransactionStatus: 事务运行状态
Spring并不直接管理事务,而是提供了多种事务管理器 ,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。
Spring事务管理器的接口是:
org.springframework.transaction.PlatformTransactionManager ,
通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。
public interface PlatformTransactionManager {
/**
*获取事物状态
*/
TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
/**
*事物提交
*/
void commit(TransactionStatus status) throws TransactionException;
/**
*事物回滚
*/
void rollback(TransactionStatus status) throws TransactionException;
}
2.2)TransactionDefinition 事物属性的定义
org.springframework.transaction.TransactionDefinition
TransactionDefinition接口中定义了5个方法以及一些表示事务属性的常量比如隔离级别、传播行为等等的常量。
我下面只是列出了TransactionDefinition接口中的方法而没有给出接口中定义的常量,该接口中的常量信息会在后面依次介绍到。
public interface TransactionDefinition {
/**
* 支持当前事物,若当前没有事物就创建一个事物
* */
int PROPAGATION_REQUIRED = 0;
/**
* 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行
* */
int PROPAGATION_SUPPORTS = 1;
/**
*如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
*/
int PROPAGATION_MANDATORY = 2;
/**
*创建一个新的事务,如果当前存在事务,则把当前事务挂起
**/
int PROPAGATION_REQUIRES_NEW = 3;
/**
* 以非事务方式运行,如果当前存在事务,则把当前事务挂起
* */
int PROPAGATION_NOT_SUPPORTED = 4;
/**
* 以非事务方式运行,如果当前存在事务,则抛出异常。
* */
int PROPAGATION_NEVER = 5;
/**
* 表示如果当前正有一个事务在运行中,则该方法应该运行在 一个嵌套的事务中,
被嵌套的事务可以独立于封装事务进行提交或者回滚(保存点),
如果封装事务不存在,行为就像 PROPAGATION_REQUIRES NEW
* */
int PROPAGATION_NESTED = 6;
/**
*使用后端数据库默认的隔离级别,Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别
*/
int ISOLATION_DEFAULT = -1;
/**
*最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
*/
int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
/**
*允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
*/
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
/**
*对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
*/
int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
/**
*最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,
* 也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能通常情况下也不会用到该级别
*/
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
/**
*使用默认的超时时间
*/
int TIMEOUT_DEFAULT = -1;
/**
*获取事物的传播行为
*/
int getPropagationBehavior();
/**
*获取事物的隔离级别
*/
int getIsolationLevel();
/**
*返回事物的超时时间
*/
int getTimeout();
/**
*返回当前是否为只读事物
*/
boolean isReadOnly();
/**
*获取事物的名称
*/
@Nullable
String getName();
}
TransactionStatus接口用来记录事务的状态 该接口定义了一组方法,用来获取或判断事务的相应状态信息.
PlatformTransactionManager.getTransaction(…) 方法返回一个 TransactionStatus 对象。返回的TransactionStatus 对象可能代表一个新的或已经存在的事务(如果在当前调用堆栈有一个符合条件的事物
public interface TransactionStatus extends SavepointManager, Flushable {
/**
* 是否为新事物
* */
boolean isNewTransaction();
/**
*是否有保存点
*/
boolean hasSavepoint();
/**
*设置为只回滚
*/
void setRollbackOnly();
/**
*是否为只回滚
*/
boolean isRollbackOnly();
/**
*属性
*/
@Override
void flush();
/**
*判断当前事物是否已经完成
*/
boolean isCompleted();
}
我们来分析@EnableTransactionManagement注解来给我们容器加入了什么组件
org.springframework.transaction.annotation.EnableTransactionManagement
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
/**
* 指定使用什么代理模式(true为cglib代理,false 为jdk代理)
* */
boolean proxyTargetClass() default false;
/**
* 通知模式 是使用代理模式还是aspectj 我们一般使用Proxy
* */
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}
我们从3.1处的源码可以分析处他通过@Import导入了TransactionManagementConfigurationSelector组件
TransactionManagementConfigurationSelector源码分析
我们可以分析处向容器中导入了二个组件
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
/**
* 往容器中添加组件 1) AutoProxyRegistrar
* 2) ProxyTransactionManagementConfiguration
* */
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) { //因为我们配置的默认模式是PROXY
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
}
首先我们来分析AutoProxyRegistrar给我们容器中干了什么?
从源码分析出,AutoProxyRegistrar为我们容器注册了一个InfrastructureAdvisorAutoProxyCreator组件
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
private final Log logger = LogFactory.getLog(getClass());
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean candidateFound = false;
//从我们传入进去的配置类上获取所有的注解的
Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
//循环我们上一步获取的注解
for (String annoType : annoTypes) {
//获取注解的元信息
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
if (candidate == null) {
continue;
}
//获取注解的mode属性
Object mode = candidate.get("mode");
//获取注解的proxyTargetClass
Object proxyTargetClass = candidate.get("proxyTargetClass");
//根据mode和proxyTargetClass的判断来注册不同的组件
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
if (mode == AdviceMode.PROXY) { //默认模式是PROXY
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean) proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
}
}
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAutoProxyCreatorIfNecessary(registry, null);
}
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//判断容器中有没有org.springframework.aop.config.internalAutoProxyCreator名字的bean定义,
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());
}
}
return null;
}
//自己注册一个org.springframework.aop.config.internalAutoProxyCreator的组件
RootBeanDefinition beanDefinition = new RootBeanDefinition(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;
}
我们从3.2.1可以分析出AutoProxyRegistrar会为我们容器中导入了一个叫InfrastructureAdvisorAutoProxyCreator的组件
①:我们来看下InfrastructureAdvisorAutoProxyCreator继承图
从继承图可看出,和之前AOP源码分析的AnnotationAwareAspectJAutoProxyCreator继承图基本相同。
由此可知,事物代理生成对象流程与AOP生成代理对象流程的套路是基本一样的。
分析InfrastructureAdvisorAutoProxyCreator 实现了如下的接口
①:实现了Aware接口(具体代表 BeanFactoryAware接口)
做了什么事情)
a:把我们的BeanFacotry容器设置到了InfrastructureAdvisorAutoProxyCreator组件中去
b: 创建了一个advisorRetrievalHelper组件 增强器检索工具
AbstractAutoProxyCreator 实现了BeanFactoryAware接口,但是马上又被AbstractAdvisorAutoProxyCreator给重写了;
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
//马上又被org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator重写了
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
//但是AbstractAdvisorAutoProxyCreator类的initBeanFactory又被InfrastructureAdvisorAutoProxyCreator重写了
org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
this.beanFactory = beanFactory;
}
②:实现了我们的接口 InstantiationAwareBeanPostProcessor类型的后置处理器,为我们容器中做了什么事情
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInitialization
postProcessBeforeInstantiation方法
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;
}
postProcessAfterInstantiation方法(没有做任何事情,直接返回)
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
③:实现了我们的接口BeanPostProcessor类型的后置处理器,为我们容器中做了什么事情
postProcessBeforeInitialization方法没有做任何事情,直接返回
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
postProcessAfterInitialization 为我们做了事情
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//有必要则生成包装后的代理类
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
然后我们在来分析一下TransactionManagementConfigurationSelector 为我们还导入了一个类ProxyTransactionManagementConfiguration
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
/**
* 为我我们容器中导入了 beanName为org.springframework.transaction.config.internalTransactionAdvisor
* 类型为:BeanFactoryTransactionAttributeSourceAdvisor 的增强器
*
* */
@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;
}
}
画图总结,后续将具体的源码分析