郑州餐饮spring声明式事务@Transactional底层⼯作原理
⽬录
引⾔
⼯作机制简述
事务AOP核⼼类释义
@Transactional
TransactionAttribute
SpringTransactionAnnotationParr
AnnotationTransactionAttributeSource
TransactionAttributeSourcePointcut
TransactionInterceptor
BeanFactoryTransactionAttributeSourceAdvisor
ProxyTransactionManagementConfiguration
事务抽象核⼼类释义
PlatformTransactionManager
TransactionStatus
TransactionDefinition
结语
引⾔
写这篇博⽂有个来由,是为了解决博主遇到的多数据源的事务问题(⽤不了JTA),所以深⼊到spring-tx的源码去学习了⼀番,⾮常有收获,最后博主的分布式事务问题也迎刃⽽解了,这个⽂章算个开篇,关于如何处理多数据源事务,待下⽂分解。本⽂涉及到的技术包含spring aop的使⽤、spring bean⽣命周期等,如果能够真正理解Transactional的⼯作原理,对排查事务相关的问题有⾮常⼤的帮助。
spring-tx版本:5.0.2
⼯作机制简述
先来看⼀张官⽅的事务简图:
spring定义了@Transactional注解,基于AbstractBeanFactoryPointcutAdvisor、StaticMethodMatcherPointcut、MethodInterceptor的aop编程模式,增强了添加@Transactional注解的⽅法。同时抽象了事务⾏为为PlatformTransactionManager(事务管理器)、TransactionStatus(事务状态)、TransactionDefinition(事务定义)等形态。最终将事务的开启、提交、回滚等逻辑嵌⼊到被增强的⽅法的前后,完成统⼀的事务模型管理。
事务AOP核⼼类释义
@Transactional
事务注解,⽤于定位aop的切⼊点,事务注解⾥包含了完整事务的所有基本属性,常见的属性如:
transactionManager:事务管理器
propagation:传播⾏为定义,枚举类型,是spring独有的事务⾏为设计,默认为PROPAGATION_REQUIRED(⽀持当前事务,不存在则新建)
isolation:隔离级别,对应数据库的隔离级别实现,mysql默认的隔离级别是 read-committed
timeout:超时时间,默认使⽤数据库的超时,mysql默认的事务等待超时为5分钟
readOnly:是否只读,默认是fal
rollbackFor:异常回滚列表,默认的是RuntimeException异常回滚
TransactionAttribute
事务属性抽象接⼝类,承载了@Transactional注解⾥的所有属性,实现类的继承关系如下类结构图,这个实例在被注解解析器创建好后,会在事务上下⽂中传递
SpringTransactionAnnotationParr
见名知意,这个类是spring的事务注解解析器,实现⾃TransactionAnnotationParr接⼝,是spring管理的事务解析器,⽤于解析@Transactional注解,将注解⾥的属性设置到TransactionAttribute的实现类属性⾥。除了这个,另还有两个实现,分别是JTA事务注解解析器,和EJB事务注解管理解析器,区别是解析的注解不同,spring是@Transactional,jta是ansaction.Transactional,EJB是javax.ejb.TransactionAttribute。这个地⽅应⽤和apache dubbo2.7.x版本解析dubbo的@rvice注解是⼀样⼀样的。关键代码如下,通过AnnotatedElementUtils类,这个类在spring-core包下,找到注解属性集AnnotationAttributes,如果不为空,则包装成事务属性集返回
@Override
@Nullable民革入党条件
public TransactionAttribute parTransactionAnnotation(AnnotatedElement element) {
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, fal, fal);
if (attributes != null) {
return parTransactionAnnotation(attributes);
天皇氏}
el {
return null;
}
}
AnnotationTransactionAttributeSource
见名知意,这个类是注解事务属性集的源,怎么理解呢?spring抽象了获取事务属性集的⾏为,⽽AnnotationTransactionAttributeSource正是@Transactional注解⽅式的事务属性集收集实现。SpringTransactionAnnotationParr就是作⽤于这个⾥⾯,⽤于发现@Transactiona注解的⽅法
TransactionAttributeSourcePointcut
也是见名知意,Pointcut属于aop的概念范畴,需要了解spring aop的知识才能看明⽩,这个就是@Transactional注解的切
点,AnnotationTransactionAttributeSource作⽤于此,⽤于寻找@Transactiona注解的⽅法,关键代码如下:
public boolean matches(Method method, Class targetClass) {
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || TransactionAttribute(method, targetClass) != null);
}
TransactionInterceptor
事务的拦截器。aop编程⾥,有了切⼊点Pointcut,就要有通知advice,我们熟悉的spring aop⾥有前置、后置、环绕、异常等通知类型,TransactionInterceptor 属于⾃定义通知模型实现,实现⾃Advice接⼝,类似于环绕通知,具体见类结构图,如下:
核⼼⽅法如下:
public Object invoke(MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be pasd the target class
// as well as the method, which may be from an interface.
Class targetClass = (This() != null ? This()) : null);
// Adapt to TransactionAspectSupport'
return Method(), targetClass, invocation::proceed);
}
被@Transactional注解的⽅法,如果被aop正确的增强了,运⾏的时候都会进⼊到这个⽅法⾥⾯,如果你发现事务不⽣效啊等等问题,可以从这⾥开始定位真实原因
BeanFactoryTransactionAttributeSourceAdvisor
事务增强器,⽤于增强添加了@Transactional注解的⽅法,上⾯提到的这些核⼼类,最终都作⽤于这⾥,⽤于寻找@Transactional注解的⽅法和织⼊事务处理逻辑
ProxyTransactionManagementConfiguration
代理事务管理的配置类,上⾯介绍的这些事务aop编程相关的在这个⾥⾯组合配置⽣效的,同时,如果你有特殊的个性化的需求,也可以⾃定义注册这个⾥⾯的实例。⽐如我嫌弃@Transactional注解太长了,想⽤@Tx注解。没关系,直接定义个TransactionAttributeSource实现,解析@Tx的⽅法,然后注册到spring的上线⽂中即可。代码如:
@Configuration(proxyBeanMethods = fal)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
辩论主题
TransactionAttributeSource transactionAttributeSource,
TransactionInterceptor transactionInterceptor) {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.tTransactionAttributeSource(transactionAttributeSource);
advisor.tAdvice(transactionInterceptor);
if (ableTx != null) {
advisor.Number("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.tTransactionAttributeSource(transactionAttributeSource);
if (Manager != null) {
interceptor.Manager);
}
return interceptor;
}
}
事务抽象核⼼类释义
PlatformTransactionManager
平台事务管理器,这是Spring事务基础设施中的中⼼接⼝。它定义了三个最最基本的事务⽅法,getTransaction获取事务,包含了事务开启的⾏为,commit提交事务,rollback回滚事务。代码如下:
public interface PlatformTransactionManager extends TransactionManager {醉过知酒浓
TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
在spring-tx中并没有提供真正的实现类,只提供了⼀个抽象派⽣类AbstractPlatformTransactionManager,并建议其他实现基于这个派⽣类,因为它预先实现了定义的传播⾏为并处理事务同步处理。⼦类必须为底层事务的特定状态实现模板⽅法,例如:begin、suspend、resume、commit等。我们平时常见的实现有:JpaTransactionManager、JtaTransactionManager、DataSourceTransactionManager等。事务管理器和事务aop处理的逻辑本⾝没有任何耦合,只需将PlatformTransactionManager实例注册到spring上下⽂中即可,事务拦截器会通过获取到@Transactional⾥的transactionManager属性去上下⽂中寻找事务管理器,并将其缓存起来,见TransactionAspectSupport.java⾥的determineTransactionManager⽅法
protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
// Do not attempt to lookup tx manager if no tx attributes are t
if (txAttr == null || this.beanFactory == null) {
return asPlatformTransactionManager(getTransactionManager());
}
String qualifier = Qualifier();
尽心竭力的意思
if (StringUtils.hasText(qualifier)) {
return determineQualifiedTransactionManager(this.beanFactory, qualifier);
}
el if (StringUtils.ansactionManagerBeanName)) {
return determineQualifiedTransactionManager(this.beanFactory, ansactionManagerBeanName);
唯美伤感图片}
el {
PlatformTransactionManager defaultTransactionManager = asPlatformTransactionManager(getTransactionManager());
if (defaultTransactionManager == null) {
defaultTransactionManager = asPlatformTransactionManager(
<(DEFAULT_TRANSACTION_MANAGER_KEY));
if (defaultTransactionManager == null) {
defaultTransactionManager = Bean(PlatformTransactionManager.class);
DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
}
}
return defaultTransactionManager;
}
}
TransactionStatus
事务状态抽象,⽤这个类的实现来维护当前的事务状态,spring-tx⾥提供了默认的实现DefaultTransactionStatus。⼀般情况下这个不需要我们关⼼,它和PlatformTransactionManager是成对存在的,⼼细的你可能已经发现了,PlatformTransactionManager⾥的三个事务⾏为传递的就是TransactionStatus。我们知道事务aop增强了添加@Transactional的⽅法,在执⾏⽅法前调⽤Transaction开启事务,之后调⽤commit⽅法提交事务,提交事务的⼊参TransactionStatus就是开启事务获得的。参见TransactionAspectSupport.java⾥的createTransactionIfNecessary⽅法TransactionDefinition
事务定义,对应了TransactionAttribute,最终通过aop得到的TransactionAttribute⾥的属性会被传递到TransactionDefinition⾥,所以TransactionDefinition⾥也包含了所有事务相关的属性,Transaction正是通过这个⾥⾯的属性去获取的事务。AbstractPlatformTransactionManager派⽣类⾥也是通过这个⾥⾯的属性去判断协调spring的事务传播⾏为的
结语
当梳理完spring-tx模块的整个结构和⼯作⽅式后,仿佛拉开了spring事务管理的⾯纱,很多事务的执⾏细节⼀览⽆余。很多事务相关的问题也就很容易解释了。⽐如常见的类中的⽅法直接调⽤⽅法事务不⽣效等问题,以及可以⾮常清晰的理解spring的传播⾏为的真正含义等。最后预告下,spring对于多数据源的事务处理解决⽅案ChainedTransactionManager
以上就是spring声明式事务@Transactional底层⼯作原理的详细内容,更多关于spring声明式事务@Transactional⼯作原理的资料请关注其它相关⽂章!