Spring-申明式事务管理

前言

事务指逻辑上的一组操作,组成这组操作的每个操作,如果成功则全部成功,如果失败则全部失败。
在IT行业的信息系统说,操作具体是指一段方法或函数的执行。
而界定信息系统操作的成功与否,是与信息的是否正常更新有关。
信息化技术而言,要保证信息正常更新就一定要满足ACID四大特征:

  • 原子性(Atomicity)
  • 一致性(Consistency)
  • 隔离性(Isolation)
  • 持久性(Durability)
    而因为其事务的持久化特征,事务往往由具有持久化功能的中间件来完成,最典型的中间件就是关系型数据库
    而在系统中,我们主要是关心如何来做事务管理,所谓的事务管理即:
  • 事务控制的范围与边界。
  • 事务传播级别的控制。
  • 事务的提交与回滚。
    下面我们通过Spring申明式事务管理为例,来看一下Spring是如何去对事务进行管理的,及Spring内部是如何实现的。

Spring申明式事务管理配置

下面我们以关系型数据库Mysql为例,来说明Spring对申明式事务管理。

导入相关依赖

Spring基础组件(IOC,DI,ASPECT):

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>

数据源

        <!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>

数据库驱动

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>

spring-jdbc(该组件会引入所依赖的spring-tx组件包)

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>

配置数据库及事务管理

创建一个配置类,使用注解@EnableTransactionManagement开启事务管理

@EnableTransactionManagement
@Configuration
public class TransactionConfig {

在配置类中创建数据源

    @Bean
    public DataSource dataSource() throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser("");
        dataSource.setPassword("");
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        return dataSource;
    }

创建对数据源的事务管理器

    @Bean
    public PlatformTransactionManager transactionManager() throws Exception{
        return new DataSourceTransactionManager(dataSource());
    }

在业务中应用事务

对指定方法应用事务管理

    @Transactional
    public void insertUser(){

对指定接口所有方法应用事务管理

@Service
@Transactional
public class UserService {

并且可以通过@Transactional注解属性,对事务进行控制:

  • propagation 控制传播级别
  • isolation 隔离级别
  • rollbackFor 回滚机制

源码分析Spring申明式事务管理实现方法

EnableTransactionManagement

通过@EnableTransactionManagement注解引入选择器TransactionManagementConfigurationSelector

@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

选择器TransactionManagementConfigurationSelector根据事务管理模式引入AutoProxyRegistrarProxyTransactionManagementConfiguration两个类;

    protected String[] selectImports(AdviceMode adviceMode) {
        switch (adviceMode) {
            case PROXY:
                return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};

AutoProxyRegistrar

其中AutoProxyRegistrar注册一个InfrastructureAdvisorAutoProxyCreator类;

    public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
        return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
    }

InfrastructureAdvisorAutoProxyCreator利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

ProxyTransactionManagementConfiguration

配置类ProxyTransactionManagementConfiguration给容器中注册事务增强器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());
        advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
        return advisor;
    }

事务增强器需要TransactionAttributeSource类实例解析事务注解,

    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource();
    }

以及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;
    }

事务拦截器TransactionInterceptor的实例是一个方法拦截器:

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {

拦截器方法在目标方法执行的时候执行拦截器链:

    protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
            throws Throwable {

        // 先获取事务相关的属性
        final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
               //再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger,最终会从容器中按照类型获取一个PlatformTransactionManager;
        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 {
                // 执行目标方法
                retVal = invocation.proceedWithInvocation();
            }
            catch (Throwable ex) {
                //如果异常,获取到事务管理器,利用事务管理回滚操作;
                completeTransactionAfterThrowing(txInfo, ex);
                throw ex;
            }
            finally {
                                //如果正常,利用事务管理器,提交事务
                cleanupTransactionInfo(txInfo);
            }
            commitTransactionAfterReturning(txInfo);
            return retVal;
        }

猜你喜欢

转载自blog.csdn.net/weixin_34122604/article/details/87411042