声明式事务环境搭建:
1、导入相关依赖
数据源、数据库驱动、Spring-jdbc模块
2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
3、给方法上标注 @Transactional 表示当前方法是一个事务方法;
4、 @EnableTransactionManagement 开启基于注解的事务管理功能;
5、配置事务管理器来控制事务;
@Bean
public PlatformTransactionManager transactionManager()
原理:
1)、@EnableTransactionManagement
利用TransactionManagementConfigurationSelector给容器中会导入组件
导入两个组件
AutoProxyRegistrar
ProxyTransactionManagementConfiguration
2)、AutoProxyRegistrar:
给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件;
InfrastructureAdvisorAutoProxyCreator:
利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执
行方法利用拦截器链进行调用;
3)、ProxyTransactionManagementConfiguration 做了什么?
3.1、给容器中注册事务增强器;
3.1.1)、事务增强器要用事务注解的信息AnnotationTransactionAttributeSource
解析事务注解
3.1.2)、事务拦截器:
TransactionInterceptor;保存了事务属性信息,事务管理器;他是一个
MethodInterceptor;在目标方法执行的时候;执行拦截器链;事务拦截器:
3.1.2.1)、先获取事务相关的属性
3.1.2.2)、再获取PlatformTransactionManager,如果事先没有添加
指定任何transactionmanger最终会从容器中按照类型获取
一个PlatformTransactionManager;
3.1.2.3)、执行目标方法如果异常,获取到事务管理器,利用事务管理
回滚操作;如果正常,利用事务管理器,提交事务
1)、@EnableTransactionManagement
利用TransactionManagementConfigurationSelector给容器中会导入组件
导入两个组件
AutoProxyRegistrar
ProxyTransactionManagementConfiguration
打来@EnableTransactionManagement的@Import(TransactionManagementConfigurationSelector.class)源码如下:
adviceMode默认是PROXY
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector {
/**
* {@inheritDoc}
* @return {@link ProxyTransactionManagementConfiguration} or
* {@code AspectJTransactionManagementConfiguration} for {@code PROXY} and
* {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()}, respectively
*/
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
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;
}
}
}
2)、AutoProxyRegistrar:
给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件;
InfrastructureAdvisorAutoProxyCreator:
利用后置处理器机制(postProcessAfterInitialization)在对象创建以后,包装对象,返回一个代理对象(增强器),代 理对象执行方法利用拦截器链进行调用;
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 annoTypes = importingClassMetadata.getAnnotationTypes();
for (String annoType : annoTypes) {
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
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) {
//省略次要代码
}
}
}
进入AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
public abstract class AopConfigUtils {
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAutoProxyCreatorIfNecessary(registry, null);
}
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAutoProxyCreatorIfNecessary(registry, null);
}
public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
//忽略非主线代码
}
可以看到最终调用
public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAutoProxyCreatorIfNecessary(registry, null);
}
InfrastructureAdvisorAutoProxyCreator 继承自 AbstractAdvisorAutoProxyCreator
顺带提一下AnnotationAwareAspectJAutoProxyCreator是创建AOP代理类里用到的继承AspectJAwareAdvisorAutoProxyCreator
而AspectJAwareAdvisorAutoProxyCreator继承自 AbstractAdvisorAutoProxyCreator
查看AbstractAutoProxyCreator的postProcessAfterInitialization
@Override
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;
}
在 wrapIfNecessary方法的wrapIfNecessary 的 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);添加条件断点条件为null!=specificInterceptors
可以看到 根据beanName=userService时对应的增强器为
[org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor: advice org.springframework.transaction.interceptor.TransactionInterceptor@3da05287]
3)、ProxyTransactionManagementConfiguration 做了什么?
3.1、给容器中注册事务增强器;
3.1.1)、事务增强器要用事务注解的信息AnnotationTransactionAttributeSource
解析事务注解
3.1.2)、事务拦截器:
TransactionInterceptor;保存了事务属性信息,事务管理器;他是一个
MethodInterceptor;在目标方法执行的时候;执行拦截器链;事务拦截器:
3.1.2.1)、先获取事务相关的属性
3.1.2.2)、再获取PlatformTransactionManager,如果事先没有添加
指定任何transactionmanger最终会从容器中按照类型获取
一个PlatformTransactionManager;
3.1.2.3)、执行目标方法如果异常,获取到事务管理器,利用事务管理
回滚操作;如果正常,利用事务管理器,提交事务总结
打开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();
advisor.setTransactionAttributeSource(transactionAttributeSource());
advisor.setAdvice(transactionInterceptor());
advisor.setOrder(this.enableTx.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;
}
}
TransactionInterceptor 继承自TransactionAspectSupport 主要的事务拦截逻辑在下面这个方法
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
Class> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
});
}
protected Object invokeWithinTransaction(Method method, Class> targetClass, final InvocationCallback invocation)
throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
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 {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
commitTransactionAfterReturning(txInfo);
return retVal;
}else {
try {
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
new TransactionCallback
总结:通过TransactionInterceptor环绕增强进行事务的增强,即进入目标方法之前开启事务,退出目标方法时提交/回滚事务。开启事务的核心就是从配置的数据源中获取一个数据库连接,关闭自动提交,然后把这个数据库连接绑定到当前线程,供后续使用 TransactionInterceptor保存了事务属性信息,事务管理器;他是一个 MethodInterceptor;在目标方法执行的时候;执行拦截器链;事务拦截器: