Spring事务
Spring事务是在数据库事务的基础上进行封装扩展的,其主要特性如下:
支持原有数据库事务的隔离级别,加入了事务传播的概念。
提供多个事务合并或隔离的功能。
提供声明式事务,让业务代码与事务分离,事务变得更易用(AOP)。
Spring提供的事务相关接口
TransactionDefinition
事务定义:事务的隔离级别,传播行为
TransactionAttribute
TransactionDefinition的子类
事务属性,实现了对回滚规则的扩展(处理异常)
PlatFormTransactionManager
事务管理器
TransactionStatus
事务运行时状态
MethodInterceptor
方法拦截器
TransactionAspectSupport
事务切面支持,内部类TransactionInfo封装了事务相关属性
Spring编程式事务
例子
Spring声明式事务
在程序主启动类上加@EnableTransactionManagement
业务方法上加@Transactional注解
源码解析
@EnableTransactionManagement注解
其中属性的含义
proxyTargetClass:使用的是JDK还是cglib动态代理
mode:SpringAOP的两种模式(ASPECTJ或PROXY)
其中@Import注解引入了间接实现了ImportSelector接口的TransactionManagementConfigurationSelector实例 (会把该实现类中返回的Class名称都定义为bean)
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
public TransactionManagementConfigurationSelector() {
}
protected String[] selectImports(AdviceMode adviceMode) {
switch(adviceMode) {
case PROXY:
return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[]{this.determineTransactionAspectClass()};
default:
return null;
}
}
private String determineTransactionAspectClass() {
return ClassUtils.isPresent("javax.transaction.Transactional", this.getClass().getClassLoader()) ? "org.springframework.transaction.aspectj.AspectJJtaTransactionManagementConfiguration" : "org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration";
}
}
selectImports方法通过获取到注解的元数据中的AdviceMode属性来装配不同的bean
其中ProxyTransactionManagementConfiguration是一个自动配置类,它注入了几个重要的事务相关的bean
BeanFactoryTransactionAttributeSourceAdvisor 可以理解为切面Aspect的角色(内部维护Point与Advisor)
TransactionAttributeSource用于获取事务属性,读取@Transactional注解上的相关属性
TransactionInterceptor事务拦截器,对事务的处理是在这个类中
执行流程
使用@EnableAspecJAutoProxy注解标注如下
此时使用AspectJ的方式实现AOP
在测试方法中打断点观察其执行流程
首先执行到CglibAopProxy中的DynamicAdvisedInterceptor中,然后获取到目标方法
在通过CglibMethodInvocation类调用目标方法
但在调用前就对目标方法进行了判断
如果此时判断不符合条件,那么该目标方法就不支持事务,属于事务失效的场景
事务失效的场景有以下几个
Bean是否是代理对象
入口函数是否是public的
数据库是否支持事务
切点是否配置正确
内部方法间调用导致事务失效
接着CglibMethodInvocation调用其父类ReflectiveMethodInvocation的proceed方法如下
在该方法中有进一步调用TransactionInterceptor的invoke方法如下
其中调用的invokeWithinTransaction()方法如下
其中通过获取事务属性等信息,在真正调用业务方法前后进行了一系列处理
在异常处理方法completeTransactionAfterThrowing中调用了如下方法
rollbackOn方法定义了事务进行回滚的规则
不配置注解RollBackfor属性则直接调用方法的默认实现
只对RuntimeException和Error进行回滚
事务传播机制
类TransactionAspectSupport中createTransactionIfNecessary方法定义了相关内容
获取事务状态
其中对传播行为,隔离级别等做了一些判断
比如上图中,当前不存在事务时对于嵌套的传播行为都是不支持的
当前存在事务时,调用如下方法
根据原有事务来返回新的事务状态