暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Spring源码分析之事务管理

Alleria Windrunner 2020-10-28
532
之前的几篇我们分别分析了Ioc以及AOP的原理,也阅读了Spring框架的源码实现。本篇我们一起来看看Spring事务框架。


Spring框架事务的本质

本质上,Spring并不直接管理事务,而是提供了事务管理接口PlatformTransactionManager,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现是有各个平台自己实现的,类图如下:

首先我们来看PlatformTransactionManager接口,平台事务管理器。该接口有具体的实现类,根据不同的持久层框架,需要选择不同的实现类。
然后是TransactionDefinition接口,事务定义信息类,其封装了事务的隔离级别,传播行为,超时,只读。
接下来是TransactionStatus接口,事务状态信息类,其封装了是否有新事物,是否已提交,是否有保存点,是否回滚。
以上三者之间的关系为平台事物管理器根据事物定义的信息TransactionDefinition进行事物管理,在管理事务中产生的一些状态记录到TransactionStatus中。


Spring框架事务管理的分类

Spring的事务管理可以分为以下两类:
  1. 编程式事务

  2. 声明式事务


编程式事务

Spring为了简化事务管理的代码,提供了模版类TransactionTemplate,所以手动编程的方式来管理事务,只需要使用该模版即可。具体步骤如下:
第一步:配置一个事务管理器,Spring使用PlatformTransactionManager接口来管理事务:
    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
    </bean>


    第二步:配置事务管理的模版:
      <!-- 配置事务管理的模板 -->
      <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
      <property name="transactionManager" ref="transactionManager"/>
       </bean>
      第三步:在需要进行事务管理的类中,注入事务管理模版:
        <bean id="accountService" class="com.cmpay.spring.service.AccountServiceImpl">    
        <property name="accountDao" ref="accountDao"/>
        <property name="transactionTemplate" ref="transactionTemplate"/>
        </bean>
        第四步:在业务层面使用模版管理事务:
          // 注入事务模板对象
          private TransactionTemplate transactionTemplate;public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
          this.transactionTemplate = transactionTemplate;}
          public void pay(final String out, final String in, final double money) {
          transactionTemplate.execute(new TransactionCallbackWithoutResult() {
          protected void doInTransactionWithoutResult(TransactionStatus status)
          // 扣钱
          accountDao.outMoney(out, money);
          int a = 10/0;
          // 加钱
          accountDao.inMoney(in, money);
             } });
          }
          但是此种方式不是很灵活,不推荐使用!


          声明式事务

          声明式事务管理又分为三种方式:
          1. 基于AspectJ的XML方式

          2. 基于AspectJ的注解 + XML混用方式

          3. 基于AspectJ的纯注解方式


          基于AspectJ的XML方式

          基于AspectJ的XML方式需要在XML文件中显示的配置事务,示例代码如下:
            -- 事务配置
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"
            <property name="driverClass" value="com.mysql.jdbc.Driver" >
            <property name="jdbcurl" value="jdbc:mysql://web01" >
            <property name="user" value="root" >
            <property name="password" value="root" >
            </bean>


            <bean class="com.cmpay.dao.AccountDaoImpl"
            <property name="dataSource" ref="dataSource" >
            </bean>


            <context:componet-scan base-package="com.cmpay.service"/ >


            --平台事务管理器
            <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
            <property name="datasource" ref="datasource" >
            </bean>


            --事务通知
            <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:method name="transfer*" >
            </tx:advice>


            --aop配置
            <aop:config>
            <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.cmpay..service.*.*(..))" >
            </aop:config>

            基于AspectJ的注解 + XML混用方式

            基于AspectJ的注解 + XML混用方式在需要事务的方法上加上注解,然后在XML中配置事务管理器。
            关于注解有两种:
            1. 类上加@Transactional:表示该类中所有的方法都被事务管理

            2. 方法上加@Transactional:表示只有该方法被事务管理


            开启事务注解:
              <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
              <property name="dataSource" ref="datasource"/>
              </bean>


              <tx:annotation-driven transaction-manager="transactionManager" />


              基于AspectJ的纯注解方式

              最后,关于纯注解的事务管理方式只需要在web线程的入口处开启事务管理即可:
                @EnableTransactionManagement

                文章转载自Alleria Windrunner,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                评论