• Spring 声明式事务


        <!--基于xml的事务配置;需要aop和tx名称空间  -->
         <!-- transactionManager事务切面 -->
         <!-- aop配置切面 -->
         <aop:config>
            <!-- 指定事务管理器要切入哪些方法进行事务控制 -->
             <aop:pointcut expression="execution(* com.lamsey.service.*.*(..))" id="txPoint"/>
             <!-- aop:advisor,建议:pointcut-ref:使用指定的切入点表达式切入事务 -->
             <aop:advisor advice-ref="myTxAdvice" pointcut-ref="txPoint"/>
         </aop:config>
         <!-- 使用tx名称空间和配置(事务建议,事务属性,事务增强) ,事务方法怎么执行
         id="myTxAdvice"自己进行命名,方便其它引用
         transaction-manager="transactionManager":指定配置哪个事务管理器
         -->
         <tx:advice id="myTxAdvice" transaction-manager="transactionManager">
             <tx:attributes>
                 <!-- 指定事务方法 :代表所有方法是事务方法-->
                 <tx:method name="*"/> 
                 <tx:method name="checkout" rollback-for="java.lang.Exception"/>
                 <tx:method name="updatePrice" propagation="REQUIRES_NEW"/>
                 <!-- 所有以get开头的方法,认为其可以优化,所以 -->
                 <tx:method name="get*" read-only="true"/>
             </tx:attributes>
         </tx:advice>

    1、事务的概述:

    在JavaEE企业级开发的应用领域,为了保证数据的完整性一致性,必须引入数据库事务的概念,所以事务管理是企业级应用程序开发中必不可少的技术。

    ●事务就是一组由于逻辑上紧密关联而合并成一个整体(工作单元)的多个数据库操作,这些操作要么都执行要么都不执行

    四个特性:

    原子性、一致性、隔离性、持久性

    2、Spring事务管理

    2.1编程式事务

    1)获取连接

    2)设置为非自动提交

    3)提交

    4)执行失败就回滚

    5)关闭相关资源

    可以将事务控制做成一个事务切面

    2.2声明式事务

    大多数情况下声明式事务比编程式事务管理更好:它将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。

    事务管理代码的固定模式作为一种横切关注点,可以通过AOP方法模块化,进而借助Spring AOP框架实现声明式事务管理

    Spring既支持编程式事务管理,也支持声明式的事务管理。

    2.3     Spring提供的事务管理器

    2.4事务管理器:

    Spring的核心事务管理抽象是PlatformTransactionManager(接口)

    2.5事务管理器的主要实现

    ①DataSourceTransactionManager:在应用程序中只需要处理一个数据源,而且通过JDBC存取。

    ②JtaTransactionManager:在JavaEE应用服务器上用JTA(Java Transaction API)进行事务管理

    ③HibernateTransactionManager:用Hibernate框架存取数据库

    3、快速的进行事务控制;
    1)、搭建事务的基础环境
              1、导包
              2、写配置;
              3、创建对应的测试表
    2)、如何快速进行事务控制;
              1、在xml中配置事务切面
     
    <!--3、配置事务切面;控制住连接池  -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="comboPooledDataSource"></property>
        </bean>
              2、配置开启基于注解的事务控制
    <tx:annotation-driven/>
              3、给事务方法上加注解
    @Transactional
     
    事务控制细节

     @Transactional的属性

     @Transactional(noRollbackForClassName="java.lang.ArithmeticException")

    * 1、控制异常回滚机制的;
         * noRollbackFor:指定哪些异常可以不回滚;
         * 运行时异常本来是都回滚的;
         * 写法:noRollbackFor=ArithmeticException.class
         *
         * noRollbackForClassName
         * 写法:noRollbackForClassName="java.lang.ArithmeticException"
         *
         *
         *
         * rollbackFor:指定哪些异常回滚;
         * 默认哪些异常回滚?
         *      运行时异常:(不受检异常);默认都回滚
         *      编译时异常:(受检异常);(必须处理,要么try-catch,要么在方法上throws)默认都不回滚;
         *              
         * 效果:数学异常回滚了,文件没找到异常不回滚
         * 写法:
         *      多个异常:rollbackFor={FileNotFoundException.class,NullPointerException.class}
         *      单个异常:rollbackFor=FileNotFoundException.class 
         * rollbackForClassName:
         * 写法:rollbackForClassName={"java.io.FileNotFoundException"}
         *
         *
         *
         *
         * readOnly:只读;
         * true:代表当前事务是一个只读事务;查询就可以进行优化,加快速度;
         *      如果某个事务真的是只读的,再加这个否则报错
         *
         * false:默认,代表当前事务读写操作都会有,不会有只读优化;
         *
         *
         *
         * timeout:超时;指就是从事务开始操作,到事务dao最后一次完成
         * 我们可以控制这个事务必须在多少秒内完成,如果没有完成,自动中断事务,回滚到之前状态
         * timeout=3;
    事务控制的两个重点问题
    1、隔离级别
    1. 事务的隔离级别
      1. 数据库事务并发问题
    假设现在有两个事务:Transaction01Transaction02并发执行。
    脏读
          [1]Transaction01将某条记录的AGE值从20修改为30
          [2]Transaction02读取了Transaction01更新后的值:30
          [3]Transaction01回滚,AGE值恢复到了20
          [4]Transaction02读取到的30就是一个无效的值。
    不可重复读
          [1]Transaction01读取了AGE值为20
          [2]Transaction02AGE值修改为30
          [3]Transaction01再次读取AGE值为30,和第一次读取不一致。
    幻读
          [1]Transaction01读取了STUDENT表中的一部分数据。
          [2]Transaction02STUDENT表中插入了新的行。
          [3]Transaction01读取了STUDENT表时,多出了一些行。
      1. 隔离级别
    数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。
    读未提交READ UNCOMMITTED
    允许Transaction01读取Transaction02未提交的修改。
    读已提交READ COMMITTED
             要求Transaction01只能读取Transaction02已提交的修改。
    可重复读REPEATABLE READ
             确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。
    串行化SERIALIZABLE
             确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。
    ⑤各个隔离级别解决并发问题的能力见下表
     
    脏读
    不可重复读
    幻读
    READ UNCOMMITTED
    READ COMMITTED
    REPEATABLE READ
    SERIALIZABLE
    ⑥各种数据库产品对事务隔离级别的支持程度
     
    Oracle
    MySQL
    READ UNCOMMITTED
    ×
    READ COMMITTED
    REPEATABLE READ
    ×
    (默认)
    SERIALIZABLE
     
     

    修改MySQL隔离级别
    SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
    
    如:SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
    
    查询MySQL的隔离级别
    SELECT @@global.tx_isolation; //查询全局隔离级别
    SELECT @@session.tx_isolation;//查询当前会话隔离级别 
    SELECT @@tx_isolation;//同上
    
    
    事务操作
    开启事务  start transaction;
    提交事务  commit;
    回滚事务  rollback;

    4、 事务的传播行为

    当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。

    事务的传播行为可以由传播属性指定。 

    事务传播属性可以在@Transactional注解的propagation属性中定义。

    传播:在共用一个事务的情况下大事务的属性配置会传播给小事务。

     注解式事务声明步骤:

    1)、配置事务切面,控制住连接池。

    2)、配置开启基于注解的事务控制 

    3)、在业务方法中加注解

    <!-- 配置事务切面,控制住连接池 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!-- 2、配置开启基于注解的事务控制 -->
        <!--transaction-manager定义事务管理的对象-->
        <tx:annotation-driven transaction-manager="transactionManager"/> 

    5、基于XML的事务配置(重点)

  • 相关阅读:
    sql-定义变量
    sql-逻辑循环while if
    iOS生命周期
    iOS系统架构
    SVN记住密码
    视图在控制权限的作用
    20140524数据库课笔记
    char和varchar区别
    多表查找
    create table约束
  • 原文地址:https://www.cnblogs.com/limingxian537423/p/7236891.html
Copyright © 2020-2023  润新知