Spring事务
Spring事务分为两种:编程式事务和声明式事务
- 编程式事务:通过编写事务相关的代码来实现对事务开启、提交和回滚的手动控制
- 声明式事务:一般是通过在方法或者类上面加@Transactional注解来实现
Spring中的事务通过AOP切面成动态代理对象,以此增强对目标方法的调用,增强的功能主要是控制事务的开启、提交和回滚。主要的接口有:
- TransactionManager:Spring事务管理器实现的标志接口,对标准事务和反应式事务都可用;
- TransactionStatus:代表事务的状态,事务代码可以使用它来获取事务的状态,也可以在失败的时候,编码式的请求一个回滚;他还包含了SavepointManager接口,用来访问保存点管理信息;注意只有底层事务管理器支持的时候,才能使用保存点管理器。
- TransactionDefinition:定义符合 Spring 的事务属性的接口,基于类似于 EJB CMT 属性的传播行为定义。
- SavepointManager:定义一个API,以一种通用的方式来编程式管理事务保存点的接口
Spring动态代理原理
Spring动态代理有两种:CGLIB动态代理和JDK动态代理。
JDK动态代理可以代理接口,不能代理没有实现接口的类;而CGLIB通过字节码技术可以动态生成被代理类的子类,从而可以代理没有实现接口的类;但是不能代理非public和final的方法,因为子类不可见。
请参考:Spring动态代理原理
关键注解
声明式事务主要通过**@EnableTransactionManagement注解声明使用事务,加载配置项;使用@Transactional**注解声明方法或类按事务方式运行;这两个注解的作用可以归纳如下图:
@EnableTransactionManagement
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
// 是否创建基于CGLIB的子类代理,默认使用标准JAVA的基于接口的JDK代理
boolean proxyTargetClass() default false;
// 事务的advice应该怎么样应用,默认是代理模式
AdviceMode mode() default AdviceMode.PROXY;
// 当多个advice在特定的加入点被使用的时候,他可以定义事务advisor的执行顺序
int order() default Ordered.LOWEST_PRECEDENCE;
}
TransactionManagementConfigurationSelector
该注解上使用@Import导入了TransactionManagementConfigurationSelector相关的配置,TransactionManagementConfigurationSelector类会根据不同的模式(代理模式,切面模式)来加载不同的配置
// 基于导入的配置类中的值选择AbstractTransactionManagementConfiguration的实现
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
// 根据EnableTransactionManagement注解中配置的模式返回配置类
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY: // 代理模式
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);
}
}
代理模式中的AutoProxyRegistrar和ProxyTransactionManagementConfiguration可以创建自动代理、生成BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource和TransactionInterceptor等事务必要的属性源和拦截器;
AutoProxyRegistrar
AutoProxyRegistrar主要是解析@EnableTransactionManagement注解的属性,根据模式等注册自动代理
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;
// 代理模式下,注册自动代理创建器
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));
}
}
}
AopConfigUtils#registerAutoProxyCreatorIfNecessary会注册org.springframework.aop.config.internalAutoProxyCreator的bean信息
public abstract class AopConfigUtils {
public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry,
@Nullable Object 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());
}
}
return null;
}
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;
}
}
ProxyTransactionManagementConfiguration
ProxyTransactionManagementConfiguration是一个配置类,他会注册BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource、TransactionInterceptor这三个bean。
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
// 由一个TransactionAttributeSource驱动的advisor, 用来为事务方法提供事务advice
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource);
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(TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
@Transactional
该注解可以标记方法或类型,使其以事务的方式运行
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
/**
* 事务管理器别名
*/
@AliasFor("transactionManager")
String value() default "";
/**
* 事务管理器
*/
@AliasFor("value")
String transactionManager() default "";
/**
* 事务的传播行为
*/
Propagation propagation() default Propagation.REQUIRED;
/**
* 事务的隔离级别
*/
Isolation isolation() default Isolation.DEFAULT;
/**
* 事务执行的超时时间
*/
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
/**
* 是否只读事务
*/
boolean readOnly() default false;
/**
* 事务回滚的异常类型
*/
Class<? extends Throwable>[] rollbackFor() default {};
/**
* 事务回滚的异常类
*/
String[] rollbackForClassName() default {};
/**
*事务不回滚的异常类型
*/
Class<? extends Throwable>[] noRollbackFor() default {};
/**
* 事务不回滚的异常类
*/
String[] noRollbackForClassName() default {};
}
Spring事务的执行原理请见下一节
Spring事务执行原理