第五章 Spring事务源码分析笔记
一、Spring事务实现
1、事务注解实现方式及配置
Spring中事务也是用AOP切面技术来实现的。
1.1、首先用注解的方式引入事务管理功能:
代码如下:
@Component
@EnableTransactionManagement(proxyTargetClass = false)
@MapperScan(basePackages = { “com.chj.dao”},annotationClass = Repository.class)
public class EnableTransactionManagementBean {
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
//这样也可以
- @Bean
public PlatformTransactionManager annotationDrivenTransactionManager(DataSource dataSource) {
DataSourceTransactionManager dtm = new DataSourceTransactionManager();
dtm.setDataSource(dataSource);
return dtm;
}
@Bean
public TransactionTemplate transactionTemplate(PlatformTransactionManager platformTransactionManager) {
TransactionTemplate transactionTemplate = new TransactionTemplate();
transactionTemplate.setTransactionManager(platformTransactionManager);
*return transactionTemplate;
}
}
引用这个注解就显示的添加了注解事务功能,但是我们自己还是需要定义数据源和事务管理平台的:
1.2、数据源定义:
com.chj.datasource.DataSourceConfiguration
@Configuration
@PropertySource(“classpath:config/core/core.properties”)
public class DataSourceConfiguration {
@Value(“${jdbc.driverClassName}“)
private String driverClass;
@Value(“${jdbc.url:jdbc}“)
private String jdbcUrl;
@Value(“${jdbc.username}“)
private String user;
@Value(“${jdbc.password}“)
private String password;
@Resource
Environment environment;
// @Bean
- *public DataSource comboPooledDataSource() {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
try {
} catch (PropertyVetoException e) {comboPooledDataSource.setDriverClass(**driverClass**);
comboPooledDataSource.setJdbcUrl(**jdbcUrl**);
comboPooledDataSource.setUser(**user**);
comboPooledDataSource.setPassword(**password**);
comboPooledDataSource.setMinPoolSize(10);
comboPooledDataSource.setMaxPoolSize(100);
comboPooledDataSource.setMaxIdleTime(1800);
comboPooledDataSource.setAcquireIncrement(3);
comboPooledDataSource.setMaxStatements(1000);
comboPooledDataSource.setInitialPoolSize(10);
comboPooledDataSource.setIdleConnectionTestPeriod(60);
comboPooledDataSource.setAcquireRetryAttempts(30);
comboPooledDataSource.setBreakAfterAcquireFailure(**false**);
comboPooledDataSource.setTestConnectionOnCheckout(**false**);
comboPooledDataSource.setAcquireRetryDelay(100);
}e.printStackTrace();
return comboPooledDataSource;
}
@Bean
public DataSource dynamicDataSource() {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
try {
} catch (PropertyVetoException e) {comboPooledDataSource.setDriverClass(**driverClass**);
comboPooledDataSource.setJdbcUrl(**jdbcUrl**);
comboPooledDataSource.setUser(**user**);
comboPooledDataSource.setPassword(**password**);
comboPooledDataSource.setMinPoolSize(10);
comboPooledDataSource.setMaxPoolSize(100);
comboPooledDataSource.setMaxIdleTime(1800);
comboPooledDataSource.setAcquireIncrement(3);
comboPooledDataSource.setMaxStatements(1000);
comboPooledDataSource.setInitialPoolSize(10);
comboPooledDataSource.setIdleConnectionTestPeriod(60);
comboPooledDataSource.setAcquireRetryAttempts(30);
comboPooledDataSource.setBreakAfterAcquireFailure(**false**);
comboPooledDataSource.setTestConnectionOnCheckout(**false**);
comboPooledDataSource.setAcquireRetryDelay(100);
}e.printStackTrace();
Map
1.3、定义事务管理平台:
//@Component
public class TransactionManagementConfigurerBean implements TransactionManagementConfigurer {
@Autowired
private DataSource dataSource;
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
DataSourceTransactionManager dtm = new DataSourceTransactionManager();
dtm.setDataSource(dataSource);
return dtm;
}
}
数据源和事务管理平台的加载都是在类ProxyTransactionManagementConfiguration进行的。
2、事务标签解析以及入口分析
spring-tx-5.1.3.RELEASE.jar!\META-INF\spring.handlers
http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler
org.springframework.transaction.config.TxNamespaceHandler
public class TxNamespaceHandler extends NamespaceHandlerSupport {
static final String TRANSACTION_MANAGER_ATTRIBUTE = “transaction-manager”;
static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = “transactionManager”;
static String getTransactionManagerName(Element element) {
return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
}
@Override
public void init() {
registerBeanDefinitionParser(“advice”, new TxAdviceBeanDefinitionParser());
registerBeanDefinitionParser(“annotation-driven”, new AnnotationDrivenBeanDefinitionParser());
registerBeanDefinitionParser(“jta-transaction-manager”, new JtaTransactionManagerBeanDefinitionParser());
}
}
org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#parse
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
registerTransactionalEventListenerFactory(parserContext);
String mode = element.getAttribute(“mode”);
if (“aspectj”.equals(mode)) {
// mode=”aspectj”
- registerTransactionAspect(element, parserContext);
if (ClassUtils.isPresent(“javax.transaction.Transactional”, getClass().getClassLoader())) {
registerJtaTransactionAspect(element, parserContext);
}
}
else { **// mode=”proxy” *AopAutoProxyConfigurer.*configureAutoProxyCreator*(element, parserContext);
} return null**;
}
2.1、事务代理入口类分析:
org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator
private static class AopAutoProxyConfigurer {
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
AopNamespaceUtils.*registerAutoProxyCreatorIfNecessary*(parserContext, element);
String txAdvisorBeanName = TransactionManagementConfigUtils.*TRANSACTION_ADVISOR_BEAN_NAME*;
if* (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
Object eleSource = parserContext.extractSource(element);
// Create the TransactionAttributeSource definition.*
- RootBeanDefinition sourceDef = *new RootBeanDefinition(
sourceDef.setSource(eleSource);**"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"**);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
*// Create the TransactionInterceptor definition. *RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
interceptorDef.setSource(eleSource);
interceptorDef.setRole(BeanDefinition.*ROLE_INFRASTRUCTURE); registerTransactionManager*(element, interceptorDef);
interceptorDef.getPropertyValues().add(“transactionAttributeSource”, new* RuntimeBeanReference(sourceName));
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef); // Create the TransactionAttributeSourceAdvisor definition.* - RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
advisorDef.setSource(eleSource);
advisorDef.setRole(BeanDefinition.**ROLE_INFRASTRUCTURE*);
advisorDef.getPropertyValues().add(“transactionAttributeSource”, new RuntimeBeanReference(sourceName));
advisorDef.getPropertyValues().add(“adviceBeanName”, interceptorName); if (element.hasAttribute(“order”)) {
advisorDef.getPropertyValues().add(“order”, element.getAttribute(“order”));
}
parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
compositeDef.addNestedComponent(new** BeanComponentDefinition(advisorDef, txAdvisorBeanName));
parserContext.registerComponent(compositeDef);
}
}
}
2.2、事务代理对象创建
org.springframework.aop.config.AopNamespaceUtils#registerAutoProxyCreatorIfNecessary
public static void registerAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.*registerAutoProxyCreatorIfNecessary*(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));*
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary*(beanDefinition, parserContext);
}
把AOP入口类封装成beanDefinition对象,把beanDefinition缓存到map中,然后实例化:
org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired
@Nullable
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;
}
*//把AOP入口类封装成beanDefinition对象,要实例化
*RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add(“order”, Ordered.*HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE*);
*//注解aop入口类的beanName名称 AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME
*registry.registerBeanDefinition(*AUTO_PROXY_CREATOR_BEAN_NAME*, beanDefinition);
return** beanDefinition;
}
代理类自动创建的核心
org.springframework.aop.config.AopConfigUtils
public abstract class AopConfigUtils {
//The bean name of the internally managed auto-proxy creator.
- *public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
//Stores the auto proxy creator classes in escalation order.**"org.springframework.aop.config.****internalAutoProxyCreator****"**;
- *private static final List
> APC_PRIORITY_LIST = new ArrayList<>(3);
static {
// Set up the escalation list…*优先级由低到高* - **APC_PRIORITY_LIST*.add(InfrastructureAdvisorAutoProxyCreator.class**);
// xml配置方式解析
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
// 注解配置方式解析
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
else {
//把beanDefinition缓存到map中
- // Still in startup registration phase*
- *this.beanDefinitionMap.put(beanName, beanDefinition);
//把beanName放到beanDefinitionNames list中,这个list着重记住,bean实例化的时候需要用到 - *this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
/\* Map of bean definition objects, keyed by bean name. */
private final Map
2.3、事务操作入口(开启、提交、回滚)
org.springframework.transaction.interceptor.TransactionInterceptor#invoke
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
- Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); // Adapt to TransactionAspectSupport’s invokeWithinTransaction…*
- *return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
- //获取事务属性类 AnnotationTransactionAttributeSource*
- TransactionAttributeSource tas = getTransactionAttributeSource(); //获取方法上面有@Transactional注解的属性*
- *final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//获取事务管理器 - *final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls. - 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;
}
备注:具体细节后面分析
3、在理解spring事务的时候必须牢记的几个概念:
Connection连接、事务、和用户会话
我们在看了jdbc代码以后可以清楚的知道,事务就是由connection对象控制的,所以connection对象是和事务是绑定的,然后用户请求过来时又需要数据库连接来执行sql语句,所以用户请求线程又是跟connection是绑定的。
在spring中事务传播属性有如下几种:
PROPAGATION_REQUIRED**:**如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS**:**支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY**:**使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW**:**新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED**:**以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER**:**以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED**:**如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
其中最常见的,用得最多就是:
PROPAGATION_REQUIRED**、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED这三种。**
事务的传播属性是spring特有的,是spring用来控制方法事务的一种手段,说直白点就是用来控制方法是否使用同一事务的一种属性,以及按照什么规则回滚的一种手段。
二、传播属性的事务控制1
1、事务传播属性概念:
1.1、未提交读read uncommited
假如开启了两个事务,事务1的隔离级别为未提交读,然后开启事务进行查询(不提交),事务2同一个表中插入一条数据,然后继续执行事务1的查询操作发现可以查询到事务2中插入的数据。
1.2、读已提交read commit
同样开始两个事务,事务1查询数据,隔离级别为read commit(未提交),事务2继续执行插入操作,这个时候回到事务1中继续查询,发现两次查询的结果不一样,这也就是所谓的的幻读。
1.3、可重复读repeatable read
同样开始两个事务,事务级别为repeatable read,操作步骤同上,发现两次查询的结果是一致的;如果这个时候我们在事务1中插入一条数据不存在的数据(已删除的数据),但是发现数据插入失败,这也是幻读现象。
1.4、可串行化
就是将事务一个接一个的串行化的去执行,这种方式可以解决幻读但是效率非常低下。
行锁:
如果多个事务操作同一行数据,比如修改同一条数据,那么同事只是成功一条,其实就是等于给这条数据加锁,先获得锁的事务先操作。
2、获取事务属性对象
2.1、入口代码分析
这个类是事务切面的Advice,所有有关spring的事务控制逻辑都在这个类里面。
com.chj.transaction.EnableTransactionManagementBean
@Component
@EnableTransactionManagement(proxyTargetClass = false)
@MapperScan(basePackages = { “com.chj.dao”},annotationClass = Repository.class)
public class EnableTransactionManagementBean {
org.springframework.transaction.annotation.EnableTransactionManagement
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
org.springframework.transaction.annotation.TransactionManagementConfigurationSelector
public class TransactionManagementConfigurationSelector extends** AdviceModeImportSelector
/\\
- * ConfigurationClassPostProcessor*
- * ConfigurationClassParser 569行掉的*
- * 收集beanName,然后封装成beanDefinition对象*
- */*
- @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**;
}
org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
/*
- * 明显是创建事务切面实例 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());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.getNumber(“order”)); ROLE_INFRASTRUCTURE*) public TransactionAttributeSource transactionAttributeSource() { return new AnnotationTransactionAttributeSource();
}
return advisor;
}
@Bean
@Role(BeanDefinition.**
}
*/\ - * 创建事务advice TransactionInterceptor*
- * */*
- @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;
}
}
2.2、创建事务advice
org.springframework.transaction.interceptor.TransactionInterceptor
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
- Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); // Adapt to TransactionAspectSupport’s invokeWithinTransaction…*
- *return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
- //获取事务属性类 AnnotationTransactionAttributeSource*
- *TransactionAttributeSource tas = getTransactionAttributeSource();
//获取方法上面有@Transactional注解的属性
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
3、事务注解解析@Transactional
这个方法就会扫描method上面的@Transactional注解,把注解里面配置的属性封装到对象中,对应的对象是:RuleBasedTransactionAttribute,获取方法上面有@Transactional注解的属性,
3.1、获取方法上面有@Transactional注解的属性方法入口:
//获取方法上面有@Transactional注解的属性
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#getTransactionAttribute
// We need to work it out.
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
// Put it in the cache.
if (txAttr == null) {
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
}
org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#computeTransactionAttribute
@Nullable
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// Don’t allow no-public methods as required.
- *if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// The method may be on an interface, but we need attributes from the target class. - // If the target class is null, the method will be unchanged.*
- Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
**// First try is the method in the target class. *TransactionAttribute txAttr = findTransactionAttribute(specificMethod); if (txAttr != null) { return** txAttr;
}
org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#findTransactionAttribute(java.lang.reflect.Method)
@Override
@Nullable
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
3.2、this.annotationParsers说明
org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#determineTransactionAttribute
private final Set
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
if (jta12Present || ejb3Present) {
this.annotationParsers = new LinkedHashSet<>(4);
//主要是用这个注解解析器,解析方法上面的@Transactional注解
- *this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}else {
this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
}
}
通过SpringTransactionAnnotationParser解析方法上面的@Transactional注解
org.springframework.transaction.annotation.SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement)
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {
@Override
@Nullable
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}else {
return null;
}
}
3.3、注解解析方法parseTransactionAnnotation分析
org.springframework.transaction.annotation.SpringTransactionAnnotationParser#parseTransactionAnnotation(org.springframework.core.annotation.AnnotationAttributes)
对象RuleBasedTransactionAttribute中分装了事务相关的配置属性,例如传播属性以及隔离级别等
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
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”));
List
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;
}
4、开启事务源码分析
4.1、开启事务代码入口
org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
// Standard transaction demarcation with getTransaction and commit/rollback calls.
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
- //获取事务属性类 AnnotationTransactionAttributeSource*
- TransactionAttributeSource tas = getTransactionAttributeSource(); //获取方法上面有@Transactional注解的属性*
- *final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//获取事务管理器 - *final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
*// Standard transaction demarcation with getTransaction and commit/rollback calls. *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;
}
4.2、进入方法createTransactionIfNecessary,分析开启事务方法
org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary
//开启事务,这里重点看
status = tm.getTransaction(txAttr);
org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
//这里重点看,.DataSourceTransactionObject拿到对象
**Object transaction = doGetTransaction();*
// Cache debug flag to avoid repeated checks.*
- *boolean debugEnabled = logger.isDebugEnabled();
if (definition == null) {
// Use defaults if no transaction definition given. - definition = new DefaultTransactionDefinition();
} //第一次进来connectionHolder为空的,所以不存在事务* - *if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave. - *return handleExistingTransaction(definition, transaction, debugEnabled);
}
// Check definition settings for new transaction. - *if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException(“Invalid transaction timeout”, definition.getTimeout());
}
// No existing transaction found -> check propagation behavior to find out how to proceed. - *if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
}**"No existing transaction found for transaction marked with propagation 'mandatory'"**);
//第一次进来大部分会走这里 - *else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
//先挂起definition.getPropagationBehavior() == TransactionDefinition.***PROPAGATION\_REQUIRES\_NEW*** ||
definition.getPropagationBehavior() == TransactionDefinition.***PROPAGATION\_NESTED***) \{
- SuspendedResourcesHolder suspendedResources = suspend(null);
*if (debugEnabled) {
}**logger**.debug(**"Creating new transaction with name \["** \+ definition.getName() + **"\]: "** \+ definition);
try {
*//创建事务状态对象,其实就是封装了事务对象的一些信息,记录事务状态的 *DefaultTransactionStatus status = newTransactionStatus( definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); *//开启事务,重点看看 DataSourceTransactionObject *doBegin(transaction, definition); *//开启事务后,改变事务状态 *prepareSynchronization(status, definition);****boolean** newSynchronization = (getTransactionSynchronization() != ***SYNCHRONIZATION\_NEVER***);
} catch (RuntimeException | Error ex) {**return** status;
resume(null, suspendedResources);
throw ex;
}
}else {
// Create “empty” transaction: no actual transaction, but potentially synchronization. - *if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn(“Custom isolation level specified but no actual transaction initiated; “ +
}**"isolation level will effectively be ignored: "** \+ definition);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
}
}
这个方法创建事务对象,事务对象往往需要跟连接挂钩,所以里面肯定会有连接对象 ConnectionHolder,在这个方法里面会首先从ThreadLocal中获取连接对象,如下:
4.3、方法doGetTransaction分析
org.springframework.jdbc.datasource.DataSourceTransactionManager#doGetTransaction
@Override
protected Object doGetTransaction() {
//管理connection对象,创建回滚点,按照回滚点回滚,释放回滚点
- DataSourceTransactionObject txObject = new DataSourceTransactionObject(); //DataSourceTransactionManager默认是允许嵌套事务的*
- txObject.setSavepointAllowed(isNestedTransactionAllowed()); //obtainDataSource() 获取数据源对象,其实就是数据库连接块对象(第一次进来为null*)
- *ConnectionHolder conHolder =
txObject.setConnectionHolder(conHolder, false);(ConnectionHolder) TransactionSynchronizationManager.*getResource*(obtainDataSource());
return txObject;
}
这个ThreadLocal中value封装了一个map,map是数据源对象DataSource和连接对象的映射关系,也就是说,如果上一个事务中建立了映射关系,下一个事务就可以通过当前线程从ThreadLocal中获取到这个map,然后根据当前使用的数据源对象拿到对应的连接对象,然后设置到事务对象中。
4.4、根据connectionHolder对象判断当前是否存在事务
事务和连接是异议绑定的,数据库连接又与用户请求回话绑定。
第一次进来connectionHolder为空的,所以不存在事务:
第二次进来connectionHolder不为空:
当方法Object transaction = doGetTransaction();执行完后,往下走:
//第一次进来connectionHolder为空的,所以不存在事务
if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
- *return handleExistingTransaction(definition, transaction, debugEnabled);
}
该方法判断当前是否存在事务,如果能从事务对象中拿到连接对象,就表示当前是存在事务的。如果不存在,也就是说是第一次创建事务。则往下走:
//第一次进来大部分会走这里
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
//先挂起
- SuspendedResourcesHolder suspendedResources = suspend(null);
*if (debugEnabled) {
}**logger**.debug(**"Creating new transaction with name \["** \+ definition.getName() + **"\]: "** \+ definition);
try {**boolean** newSynchronization = (getTransactionSynchronization() != ***SYNCHRONIZATION\_NEVER***);
*//创建事务状态对象,其实就是封装了事务对象的一些信息,记录事务状态的*
- *DefaultTransactionStatus status = newTransactionStatus(
*//开启事务,重点看看 DataSourceTransactionObject *doBegin(transaction, definition);* //开启事务后,改变事务状态*definition, transaction, **true**, newSynchronization, debugEnabled, suspendedResources);
- prepareSynchronization(status, definition);
*return status;
}
后续源码分析详见第六章。
还没有评论,来说两句吧...