什么是事务
事务是数据库操作的最小单元,是作为单个逻辑单元执行的一系列操作;这些操作作为一个整体向系统提交,要么都执行,要么都不执行;事务是一组不可分割的操作集合。通俗点说为了达到某个目的而做了一系列的操作,要么一起成功,要么一起失败。
事务的特性
- 原子性:事务中所有操作是不可再分割的原子单位。事务中操作要么全部执行成功,要么全部执行失败。
- 一致性:事务执行后,数据库的状态与其业务规则保持一致。
- 隔离性:并发操作中,不同的事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
- 持久性:一旦事务提交成功,事务中所有数据都被持久化到数据库中,即使提交事务后数据库崩溃,在数据库在重启后也必须保证通过某种机制进行恢复数据。
事务的隔离级别
数据库事务的隔离级别有4种,由低到高分别为Read uncommitted、Read committed、Repeatable Read、Serializable。在事务的并发操作中可能会出现脏读、不可重复读、幻读、事务丢失。
- 脏读(读取了未提交的新事务,然后被回滚了):事务A读取了事务B中尚未提交的数据。如果B事务回滚,则A就读取了错误的数据。
- 不可重复读(读取了提交的新事务,指更新操作):在对数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔时,被另一个事务修改并提交了。
- 幻读(读取了提交的新事物,值新增和删除操作)在事务A多次读取中,事务B做了新增和删除操作,造成事务A多次读取的结果不一致。
- Read uncommitted:允许一个事务读取另一个事务未提交的数据。会产生脏读。
- Read committed:一个事务要等另一个事务提交完后才可以读取。会产生不可重复读。
- Read committed:在开始读取数据时,不允许做修改操作。会产生幻读。
- Serializable:操作会锁表,笔辩脏读幻读不可重复读。
Spring事务的传播特性
Spring中总共给出了7个传播特性。REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED
@Transactional
public void a(){
// 省略……
b();
// 省略……
}
@Transactional
public void b(){
// 省略……
}
事务的传播特性解决的问题就是方法相互嵌套时的事务解决方式。当a方法调用b方法时,b方法出现了异常,b方法回滚,a方法是否需要回滚;如果a方法出现异常,a方法回滚,b方法是否需要回滚。
- 不要事务
- NEVER:如果都没有事务以非事务方式运行,有事务的话抛出异常。
- NOT_SUPPORTED:如果没有事务以非事务方式运行,有事务的话将事务挂起。
- 可有可无事务
- SUPPORTS:如果没有事务以非事务方式运行,如果有就使用当前事务。
- 必须有事务
- REQUIRES_NEW:如果没有事务,就创建事务。如果有事务,将原来事务挂起,自己开启一个事务。
- NESTED:如果没有事务,就创建一个事务。如果有就在当前事务嵌套事务。
- REQUIRED:如果没有新建一个事务,如果有使用当前事务。
- MANDATORY:如果没有抛出异常,如果右使用当前事务
Spring事务管理的原理
说起Spring的声明式事务时,提到注解一切可能都要从@EnableTransactionManagement来开始说起。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}
EnableTransactionManagement注解中引用了TransactionManagementConfigurationSelector类。
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
// 注册AutoProxyRegistrar和ProxyTransactionManagementConfiguration这两个类
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
private String determineTransactionAspectClass() {
return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
}
}
TransactionManagementConfigurationSelector这个类中的进行注册了AutoProxyRegistrar和ProxyTransactionManagementConfiguration这两个类。下面先进行看下ProxyTransactionManagementConfiguration这个类。
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// 声明适配器
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
// 设置@Transactional注解的解析属性
advisor.setTransactionAttributeSource(transactionAttributeSource());
// 设置advice方法拦截
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
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;
}
}
可以看到ProxyTransactionManagementConfiguration加了@Configuration注解,内部声明了一些Bean。注册了BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource和TransactionInterceptor这几个类。在创建BeanFactoryTransactionAttributeSourceAdvisor时,Spring是将其直接进行new出来。
@SuppressWarnings("serial")
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
@Nullable
private TransactionAttributeSource transactionAttributeSource;
// 切入点,方法匹配是否有@Transactional注解
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
}
public void setClassFilter(ClassFilter classFilter) {
this.pointcut.setClassFilter(classFilter);
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}
看完ProxyTransactionManagementConfiguration之后,接下来我们将看下AutoProxyRegistrar。
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> 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;
// 在这里注册了InfrastructureAdvisorAutoProxyCreator
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));
}
}
}
InfrastructureAdvisorAutoProxyCreator的继承体系
InfrastructureAdvisorAutoProxyCreator是一个后置处理器,会在bean加载后检查是否要生成代理对象。
@SuppressWarnings("serial")
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
@Nullable
private ConfigurableListableBeanFactory beanFactory;
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
this.beanFactory = beanFactory;
}
@Override
protected boolean isEligibleAdvisorBean(String beanName) {
return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
}
}
在这个类中基本上看不到什么处理方法,接着我们去看下父类AbstractAdvisorAutoProxyCreator的一些方法信息。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 获取所有的候选增强器
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 筛选出可用的增强器
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
// 返回所有增强器
return this.advisorRetrievalHelper.findAdvisorBeans();
}
我们继续看下父类AbstractAutoProxyCreator中的一些方法
// 后置处理器
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 生成代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 获得所有增强切面
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
总结
- 通过@EnableTransactionManagement注解来进行注入
- EnableTransactionManagement注解中引入了TransactionManagementConfigurationSelector
- TransactionManagementConfigurationSelector进行注册AutoProxyRegistrar和ProxyTransactionManagementConfiguration
- ProxyTransactionManagementConfiguration类中进行声明了BeanFactoryTransactionAttributeSourceAdvisor(适配器)、TransactionAttributeSource(@Transactional注解解析器)、TransactionInterceptor(方法拦截器)。在适配器创建时又引入了TransactionAttributeSourcePointcut(切入点,方法匹配是否有@Transactional注解)
- AutoProxyRegistrar是一个ImportBeanDefinitionRegistrar的实现类,在后面帮我们注册InfrastructureAdvisorAutoProxyCreator。
- InfrastructureAdvisorAutoProxyCreator判断类是否需要代理,来帮我们进行代理类。