通常Spring事务管理的配置都是XML或者声明式注解的方式,然后想要学习其运行的原理,从TransactionProxyFactoryBean深入更合适。我们从事务相关的核心类开始,逐步介绍Spring事务的运行机制。
Spring事务核心类
Spring事务的构成,基本有三个部分,事务属性的定义,事务对象及状态信息的持有,事务管理器的处理。
事务属性的定义
- TransactionDefinition 事务定义(传播属性,隔离属性,timeout等)
- TransactionAttribute 事务属性接口 (继承TransactionDefinition),常用的实现是RuleBasedTransactionAttribute
- TransactionAttributeSource 事务属性数据源,可以根据method和Class获取TransactionAttribute(注解方式的实现为AnnotationTransactionAttributeSource,编程方式的实现为NameMatchTransactionAttributeSource)
事务对象及状态信息的持有
- Transaction 事务对象,由具体的事务管理器实现返回
- TransactionStatus 事务状态,持有事务对象以及事务本身的属性及状态,每次事务方法执行前,生成一个新的TransactionStatus,但如果不需要创建新事务,则持有的事务和上层一致
- TransactionInfo 事务信息,持有事务属性,事务状态,事务连接点(方法路径),事务管理器,每次事务方法执行,生成新的TransactionInfo,并且绑定到当前线程(ThreadLocal),同时持有上一事务信息对象,形成链式结构。
事务管理器的处理
- PlatformTransactionManager事务管理接口,AbstractPlatformTransactionManager为其抽象实现(实现了getTransaction,commit,rollback模板方法),常用的实现如JDBC的事务管理实现DataSourceTransactionManager
TransactionProxyFactoryBean
TransactionProxyFactoryBean实现了FactoryBean和InitializingBean接口,FactoryBean支持对需要事务支持的类的代理,InitializingBean初始化事务环境的准备工作,完成代理对象的创建。我们再来看下xml的配置:
1 | <!-- userManager事务代理类 --> |
需要配置的有三个,原始对象,事务属性和事务管理器。其中原始对象用来生成代理对象,而事务属性和事务管理器都设置到一个很重要的对象中,即TransactionInterceptor,事务拦截器,对应AOP中的增强类,完成事务管理和方法本身的结合。
回到TransactionProxyFactoryBean的构造,其主要实现定义在抽象父类AbstractSingletonProxyFactoryBean中。在初始化方法afterPropertiesSet中,使用最原始的ProxyFactory, 完成了代理对象的创建。
1 | AbstractSingletonProxyFactoryBean.java |
其中核心增强拦截器有子类实现其创建方法createMainInterceptor
1 | TransactionProxyFactoryBean.java |
TransactionAttributeSourceAdvisor的默认pointcut类是TransactionAttributeSourcePointcut,定义在其内部。
1 | TransactionAttributeSourceAdvisor.java |
TransactionAttributeSourcePointcut是一个抽象类,在TransactionAttributeSourceAdvisor匿名实现的。我们来看下TransactionAttributeSourcePointcut的实现,它继承了StaticMethodMatcherPointcut,一个对方法进行匹配的基本Pointcut类,实现matches方法。
1 | public boolean matches(Method method, @Nullable Class<?> targetClass) { |
而事务属性数据源从哪里设置的呢?我们在上面的TransactionAttributeSourceAdvisor匿名实现的TransactionAttributeSourcePointcut类中可以发现TransactionAttributeSource是从TransactionInterceptor中获取的。而TransactionInterceptor的TransactionAttributeSource是哪里设置的呢?来源于XML配置的properties对象transactionAttributes,在TransactionProxyFactoryBean的setTransactionAttributes方法中。
1 | public void setTransactionAttributes(Properties transactionAttributes) { |
transactionAttributes实际被设置到TransactionInterceptor中
1 | public void setTransactionAttributes(Properties transactionAttributes) { |
这里看到TransactionAttributeSource的实现是NameMatchTransactionAttributeSource。在其内部维护了一个方法名和事务属性的Map
1 | private Map<String, TransactionAttribute> nameMap = new HashMap<>(); |
因此对哪个方法进行事务AOP的切入的原理就很清楚了。接下来就是核心拦截器TransactionInterceptor的解析。
TransactionInterceptor
TransactionInterceptor实现了Spring AOP的基本增加接口MethodInterceptor,实现invoke方法
1 | public Object invoke(final MethodInvocation invocation) throws Throwable { |
具体实现由TransactionInterceptor抽象子类TransactionAspectSupport的invokeWithinTransaction方法执行
1 | protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, |
这个方法就是事务执行的核心部分,通过环绕增加,完成方法不同执行结果(成功或异常)对应事务的处理。当然前提是要先创建事务,来看createTransactionIfNecessary方法
1 | protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm, |
事务对象及状态的维护由具体的事务管理器来管理,下一章我们具体讨论事务管理器,这里主要关注它的构建骨架。返回的事务状态对象TransactionStatus,需要再次被prepareTransactionInfo方法填充
1 | protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm, |
这里非常重要的是维护了一个线程级别的事务信息的栈结构。
事务信息组建完成后,就是方法本身的执行。如果发生异常,则事务该如何处理,由completeTransactionAfterThrowing方法执行
1 | protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) { |
在上面的方法中,核心就是判断原始方法抛出的异常是否要回滚事务,如果是,则调用事务管理器回滚事务,如果不是,则直接提交事务。
对异常是否回滚事务的判断是由事务属性中的rollbackFor和noRollbackFor共同决定的,默认都没有配置时,执行DefaultTransactionAttribute基本事务属性类中的rollbackOn方法
1 | public boolean rollbackOn(Throwable ex) { |
即当异常为运行时异常或Error时,就会回滚,否则直接提交。直接提交这一点也是需要格外注意的。
如果方法运行没有异常,执行完成后,就需要提交事务,由commitTransactionAfterReturning方法执行
1 | protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) { |
调用事务管理器执行commit来提交事务。
至此,对于TransactionProxyFactoryBean的AOP代理生成以及TransactionInterceptor核心增强中事务执行的原理都基本解析清楚了,下一章介绍事务管理器的运行机制以及DataSourceTransactionManager如何和JDBC事务接口的交互。