一、理论
1、作用
@Transactional 的作用是以 @Transactional 修饰的方法会开启事务,如果方法抛出异常时会触发事务的回滚操作。
二、原理
1、主要相关包
首先,要想使用 @Transactional 注解,起码有三个包:
第一个是 spring-tx,@Transactional 注解属于该包下的;
第二个包方式 spring-aop 包,因为对于 公共方法上含有 @Transactional 的 BeanDefinition,初始化 bean 时会创建 CGLIB 动态代理对象,而创建代理对象的逻辑在该包下;
第三个包是 spring-boot-autoconfigure 包,该包会在某个 配置类上添加 @EnableTransactionManagement 注解,该注解下有 @Import 注解,通过 @Import 注解注入一个 bean 后置处理器:InfrastructureAdvisorAutoProxyCreator,而 bean 在初始化过程中正是调用 该 bean 后置处理器的 postProcessAfterInitialization(); 完成动态代理对象的创建。
2、主要类
@EnableTransactionManagement
InfrastructureAdvisorAutoProxyCreator
CglibAopProxy.DynamicAdvisedInterceptor
transactionInterceptor
3、代码逻辑
一、首先 spring-boot-autoconfigure 包下在某个配置类上有 @EnableTransactionManagement 注解,该注解下有一个注解:@Import(TransactionManagementConfigurationSelector.class) ,TransactionManagementConfigurationSelector 类实现 ImportSelector 接口,selectImports(); 注入了一个 bean 后置处理器的 beanDefinition:InfrastructureAdvisorAutoProxyCreator。
二、公共方法含有 @Transactional 的 serviceImpl 层的 bean 在初始化的最后一步:执行所有 bean 后置处理的 postProcessAfterInitialization(); 中会调用 InfrastructureAdvisorAutoProxyCreator 对象的 postProcessAfterInitialization();,该方法中会判断该 bean 中是否具有 @Transactional 修饰的公共方法,如果有,会使用 CGLIB 动态代理创建该 bean 的动态代理对象,该对象被放到一级缓存中。
三、在通过该动态代理对象调用方法访问数据库时,会执行动态代理对象的拦截器链,其中第一个拦截器链为 CglibAopProxy.DynamicAdvisedInterceptor,会直接调用该对象的 intercept();,该方法中会判断我们执行的方法上是否是 @Transactional 修饰的公共方法,如果是,则会调用 transactionInterceptor.invoke();
四、transactionInterceptor.invoke(); 主要有三步:
第一步:创建事务,即 connection.setAutoCommit(false);
第二步:执行原有方法,即访问数据库
第三步:执行提交(connection.commit())或回滚(connection.rollback())操作
三、作用
针对方法逻辑中有多个增删改操作,可以通过在方法上添加 @Transactional,从而开启事务。