• Spring事务管理——基础会用篇


      之前说到Spring的事务管理 一直很懵逼 ,只知道事务管理大概是干嘛的。

      网上的博客都是用 银行转账来解释 事务管理,哈哈哈 那我也用这个吧,这个例子的确是最好的。

      说是两个人相互转账,A转500块钱给B,至于A为啥转钱给B那是她们直接的事情。那么问题来了,比如A转钱给B的时候,突然断电了,A 的钱已经从数据库中扣了,但并没有执行存入到B账户的操作。如果没有事务管理,那这500快就没了  但有了事务管理 那之前的这个从A扣的钱 就会回滚 本次操作 就不成功。所以A就不会扣钱 。至于原理是什么,就见下回分享吧。

      言归正传。

      Spring的事务管理分为两种:

      1:编程式的事务管理

        手动编写代码进行事务管理(很少使用)

      2:声明式的事务管理

        2.1 基于TransactionProxyFactoryBean的方式(很少使用)。

        2.2 基于AspectJ的xml方式(经常使用)

        2.3 基于注解@Transaction的方式(经常使用)

      那么我们就来详细说说 这几种事务管理是怎么实现的。

      一:首先 我们得先聊一聊事务的几个要素

      1:事务的传播行为,Propagation 。其主要的参数值有:

        PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 (比较常用)
        PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。 
        PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 
        PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 
        PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 
        PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

      2:事务的隔离级别:isolation   

        Serializable:最严格的级别,事务串行执行,资源消耗最大;
        REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
        READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
        Read Uncommitted:保证了读取过程中不会读取到非法数据。
      3:只读性:read-only   true表示只读 false表示可读可写

      4: 发生哪些异常需要回滚:rollback-for (...Exprofesion)
      5:发生哪些异常不回滚 no-rollback-for
      6:timeout :过期信息

      

      二:我们从比较常用的声明式事务管理开始介绍。

       2.1 基于AspectJ的xml方式(经常使用)

        基于AspectJ的和基于注解的事务管理都是采用AOP协助的事务管理方式。而且是Spring的项目,所以在Spring必要的jar包的基础上来进行的

        所以,首先我们需要进入必要的jar包,这里我们采用的是maven引入相关jar包

        

    <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aop</artifactId>
          <version>4.1.6.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>aspectj</groupId>
          <artifactId>aspectjrt</artifactId>
          <version>1.5.3</version>
        </dependency>
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.8.4</version>
        </dependency>
        <dependency>
          <groupId>aopalliance</groupId>
          <artifactId>aopalliance</artifactId>
          <version>1.0</version>
        </dependency>
        <dependency>
          <groupId>cglib</groupId>
          <artifactId>cglib</artifactId>
          <version>3.2.4</version>
        </dependency>

      然后 我们在Spring的配置文件中加入如下代码:

      首先是注入Spring的事务管理,因为所以的事务管理都是他来实现的。其中dataSourse是你的c3p0链接池,这里就不多做介绍。

      

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    
            <property name="dataSource" ref="dataSource"/>
        </bean>

    然后是配置事务的相关属性

    <!--基于aspectj的事务声明式事务管理方式-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <!--
                    propagation     :事务传播行为
                    isolation       :事务隔离级别
                    read-only       :只读
                    rollback-for    :发生哪些异常需要回滚
                    no-rollback-for :发生哪些异常不回滚
                    timeout         :过期信息
                -->
          <!--这个是需要进行事务的管理的那个方法名 这里的name一般是 “sava*” “update*” list*” 表示以sava开始的方法都要进行事务的管理-->
    <tx:method name="refnumber" propagation="REQUIRED" isolation="DEFAULT"/> </tx:attributes> </tx:advice>

    然后就是进行AOP的切点和切面配置 这里的切入点是 demo下面的servcie.impl的所以包的所有类中的所以方法

    <aop:config proxy-target-class="true">
            &lt;!&ndash;配置切入点&ndash;&gt;
            <aop:pointcut id="pointCut1" expression="execution(* demo.service.impl.*.*(..))"></aop:pointcut>
            &lt;!&ndash;配置切面&ndash;&gt;
            <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut1"/>
        </aop:config>

    所以 我们就完成了事务管理的配置

    测试如下:

    在有异常的时候,第一步虽然执行了 但数据库操作并没有成功。

      2.3 基于注解@Transaction的方式(经常使用)

      这个方式 就更加简单了

      

     <!--事务管理-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          
            <property name="dataSource" ref="dataSource"/>
        </bean>
       <!--开启注解-->
        <tx:annotation-driven transaction-manager="transactionManager"/>

      在需要进行事务管理的地方 给一个@Transactional的注解就可以。如图所示:其中的配置文件在()中补充。

      

     由于时间原因:后面两种不常用的下回再补充。

  • 相关阅读:
    在VS2010下,用QT,创建一个Opencv应用程序
    SNR(信噪比)与 特定分布噪声的关系初探
    Qt学习笔记_FindDialog
    关于reduced rank regression的一些看法
    实时摄像头人眼跟踪: RealTime Tracking Of Human Eyes Using a Webcam
    L1_APG_Tracker实现代码剖析
    CVPR2013 感兴趣论文汇总
    使用PowerDesigner 15对现有数据库进行反向工程(图解教程)(转)
    大数据量高并发的数据库优化
    rtmp和rtsp的区别
  • 原文地址:https://www.cnblogs.com/luffyu/p/7307938.html
Copyright © 2020-2023  润新知