Spring—事务处理

Spring—事务处理

  1. 什么是事务

    • mysql中提出事务,事务是指一组sql语句的集合,集合中有多条sql语句
    • 可能是insert,update,select,delete,我们希望这些多个sql语句都能成功或者失败,这些sql语句的执行是一致的,作为一个整体执行
  2. 什么时候想到使用事务

    • 当操作涉及到多个表,或者多个sql语句的insert,update,select,delete。需要保证这些语句都是成功才能完成功能,或者都失败,保证操作是符合要求的
    • 在Java代码中写程序,控制事务, 此时事务应该放在service类的业务方法上,因为业务方法会调用多个dao方法,执行多个sql语句
  3. 通常使用JDBC访问数据库,还是mybatis访问数据库,怎么处理事务

    • JDBC访问数据库,处理事务 Connection conn;conn.comit();conn.rollback();
    • mybatis访问数据库,处理事务,SqlSession.comit();SqlSession.rollback();
    • hibernate访问数据库,处理事务,Session.comit();Session.rollback();
  4. 3中的事务处理方式有什么不足

    • 不同的数据库访问技术,处理事务的对象,方法不同,需要了解不同数据库访问技术使用事务的原理
    • 掌握多种数据库中事务的处理逻辑。什么时候提交事务,什么时候回滚事务
    • 处理事务的多种方法
    • 总结:就是多种数据库的访问技术,有不同的事务处理机制,对象,方法
  5. 怎么解决不足

    • spring提供了一种处理事务的统一模型,能使用统一步骤,方式完成多种不同的数据库访问技术的事务处理
    • 使用spring的事务处理机制,可以完成 访问数据库的事务处理
    • 使用spring的事务处理机制,可以完成hibernate访问数据库的事务处理
    • spring的事务处理模型:抽象了事务处理各个事务的处理步骤
    • 声明事务:把事务相关的资源和内容都提供给spring,spring就能处理事务提交,回滚了,几乎不用代码
  6. 处理事务,需要怎么做,做什么

  • spring处理事务的模型,使用的步骤都是固定的。把事务使用的信息提供给spring就可以了

(1)事务内部提交,回滚事务,使用的事务管理器对象,代替你完成commit,rollback

​ 事务管理器是一个接口和他的众多实现类,

  • 接口: PlatformTransactionManager ,定义了事务重要方法commit , rollback实现类: spring把每一种数据库访问技术对应的事务处理类都创建好了。
  • mybatis访问数据库—spring创建好的是DatasourceTransactionManagehibernater访问数据库----spring创建的是HibernateTransactionManager
  • 怎么使用:如何告诉spring,你用的那种数据库访问技术
    • 声明数据库访问技术对于的事务管理器实现类,在spring的配置文件中使用声明就可以了
    • 你要使用mybatis访问数据库,你应该在xml配置文件中<bean id=xxx" class=" . …DatasourceTransactionManager">
  • 你的业务方法需要什么样的事务,说明需要事务的类型。说明方法需要的事务:
    • 你的业务方法需要什么样的事务,说明需要事务的类型。说明方法需要的事务:
    • 事务的隔离级别:有4个值
    • DEFAULP:采用DB默认的事务隔离级别。MySql的默认为REPEATABLE_READ;Oracle默认为 READ_COMITTRED.READ
    • UNCOMMITTED:读未提交。未解决任何并发问题
    • READCOMMITTED:读已提交。解决脏读,存在不可重复读与幻读.
    • REPEATABLE READ:可重复读。解决脏读、不可重复读,存在幻读
    • SERIAL,1ZABLE:串行化。不存在并发问题。

(2)事务的超时时间:表示一个方法最长的执行时间,如果方法执行时超过了时间,事务就回滚

​ 单位:秒,整数值,默认是-1

  • (重要)事务的传播行为:控制业务方法是不是有事务的,是什么样的事务的

  • 7个传播行为,表示你的业务方法调用时,业务在方法之间是如何使用的

    • PROPAGATION_REQUIRED
    • PROPAGATION_REQUIRES_NEW
    • PROPAGATION_SUPPORTS

    重点掌握以上三个

    • PROPAGATION_MANDATORY
    • PROPAGATION_NESTED
    • PROPAGATION_NEVER
    • PROPAGATION_NOT_SUPPORTED

    几乎不用

(3)spring提交事务,回滚事务的时机

  • 当你的业务方法,执行成功,没有异常抛出,当方法执行完毕,spring在方法执行后提交事务。事务管理器commit

    当你的业务方法抛出运行时异常或ERROR,spring执行回滚,调用事务管理器的rollback

    运行时异常的定义:RuntimeException和他的子类都是运行时异常,例如NullPointException ,NumberFormatException

  • 当你的业务方法抛出非运行时异常,主要是受查异常时,提交事务

    受查异常:在你写代码中,必须处理的异常。例如IOException,SQLException

  1. 总结spring事务

    1. 管理事务的是事务管理器和他的实现类
    2. spring的事务是一个统一模型
      • 指定要使用的事务管理器实现类,使用
      • 指定那些类,那些方法需要加入事务的功能
      • 指定方法需要的隔离级别,传播行为,超时
    3. 你需要告诉spring,你项目中 类信息,方法名称,方法事务传播行为

一、事务的环境项目步骤

  1. 新建maven项目

  2. 加入maven依赖

    1. spring依赖
    2. mybatis依赖
    3. mysql驱动
    4. spring事务的依赖
    5. mybatis和spring集成的依赖:mybatis官方用的,用来在spring项目中创建mybatis的SqlSessionFactory,dao对象
  3. 创建实体类

    Sale,Goods

  4. 创建dao接口和mapper文件

    SaleDao接口,GoodsDao接口

    SaleDao.xml,GoodsDao.xml

  5. 创建mybatis主配置文件

  6. 创建Service接口和实现类,属性是dao

  7. 创建mybatis的配置文件:声明mybatis的对象交给spring创建

    1. 数据源
    2. SqlSessionFactory
    3. Dao对象
    4. 声明自定义的service
  8. 创建测试类,获取Service对象,通过service调用dao完成数据库的访问

二、spring框架中提供的事务 处理方案

1、适合中小项目使用,注解方案

  • spring框架自己用aop实现给业务方法增加事务的功能,使用@Transactional注解增加事务。

  • @Transactional注解是spring框架自己注解,放在public方法的上面,表示当前方法具有事务。

  • 可以给注解的属性赋值,表示具体的隔离级别,传播行为,异常信息等

  • @Transactional的步骤

    1.声明事务管理器对象

    <bean id = "xx" class = "DataSourceTransactionManager"
    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--连接数据库,指定数据源-->
      <property name="dataSource" ref="myDataSource"/>
    </bean>
    

    2.开启事务注解驱动,告诉spring,要使用注解的方式管理事务

    使用aop机制,创建@Transactional所在的类代理对象,给方法加入事务功能

    spring给业务加事务:在业务方法之前,先开启事务,在业务方法之后提交或回滚事务,使用aop环绕通知

    <!--开启事务注解驱动,告诉spring使用注解管理事务,创建代理对象
    	transaction-manager:事务管理对象的id
    -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
    @Around("要增加的事务功能的业务方法名称")
    Object myAround(){
        开启事务,spring自己开
        try{
            buy(1001,11);
            spring的事务管理.commit();
        }catch(Exception e){
            spring的事务管理.rollback();
        }
    }
    

    3.在public方法上面加入@Transactional

    • 必须放在public方法上面

    • rollbackFor:表示发生指定的异常一定回滚

    • 处理逻辑:

      • 1.spring收首先检查方法抛出的异常是不是在rollbackFor的属性值中,如果异常在rollbackFor列表中,不管是什么类型的异常,一定回滚
      • 2.如果抛出的异常不在rollbackFor列表中,spring会判断异常是不是RuntimeException,如果是一定回滚
    • 法一:

      @Transactional(
      	propagation = Propagation.REQUIRED,     
      	isolation = Isolation.DEFAULT,
      	readOnly = false,
      	rollbackFor = {
              
              
      		NullPointerException.class,NotEnoughException.class
      	}
      )
      
    • 法二:

      @Transactional//使用的是事务控制的默认值,默认的传播行为是REQUIRED。隔离级别是DEFAULT,默认抛出运行时异常,回滚事务
      

2.适合大型项目aspecj框架功能

  • 有很多的类,方法,需要大量的配置事务,使用aspectj框架功能,在spring配置文件中声明类,方法需要的事务。这种方式业务方法和事务配置完全分离。

  • 实现步骤:都是在xml配置文件中实现

    1. 要使用的是aspectj框架,加入依赖

      	<!--aspectj代码依赖-->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.5.RELEASE</version>
          </dependency>
      
    2. 声明事务管理器对象

      <bean id = "xx" class = "DataSourceTransactionManager"
      
      <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="myDataSource"/>
      </bean>
      
    3. 声明方法需要的事务类型(配置方法的事务属性{隔离级别,传播行为,超时})

      	<!--
                id:自定义名称,表示 <tx:advice>和</tx:advice>之间的配置内容
                transaction-manager:事务管理器对象的id
          -->
          <tx:advice id="myAdvice" transaction-manager="transactionManager">
              <!-- <tx:attributes>:配置事务属性-->
              <tx:attributes>
                  <!--<tx:method:给具体的方法配置事务属性,method可以有多个,分别给不同的方法设置事务属性
                      name:方法名称,(1)完整的方法名称,不带有包和类
                                    (2)方法可以使用通配符,*,表示任何字符
                      propagation :传播行为,枚举值
                      isolation :隔离级别
                      rollback-for :你指定的异常类名,全限定类名。发生异常―定回滚
                  -->
                  <tx:method name="buy" propagation="REQUIRED" isolation="DEFAULT"
                       	 rollback-for="java.lang.NullPointerException,nuc.gjq.excep.NotEnoughException"/>
              </tx:attributes>
          </tx:advice>
      
    4. 配置aop:指定那些类要创建代理

      	 <aop:config>
              <!--配置切入点表达式:指定那些包中类,要使用事务
                  id:切入点表达式的名称,唯一值
                  expression:切入点表达式,指定那些类要使用事务,aspectj会创建代理对象
              -->
              <aop:pointcut id="servicePt" expression="execution(* *..service..*.*(..))" />
              <!--配置增强器:关联advice和pointcut
                  advice-ref:通知,上面tx:advice那里的配置
                  pointcut-ref:切入点表达式的id
              -->
              <aop:advisor advice-ref="myAdvice" pointcut-ref="servicePt"/>
          </aop:config>
      

猜你喜欢

转载自blog.csdn.net/qq_45414532/article/details/115531573