Spring事务管理&数据库隔离级别

 

一、spring事务管理

1、 什么是事务

  事务(Transaction)是多个操作数据库的步骤(CRUD)的集合,是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。达到保持数据完整性的作用。

 

2、 事务特点

  1)  原子性

  一个事务所有对数据库操作是一个最小单位,不可细分;要么执行,要么不执行

  2)  隔离性

  事务之间可以同时执行,不会互相干扰,是隔离的

  3)  一致性

  事务执行成功数据库变更,事务执行失败数据库不变更,即事务一致性

  4)  持久性

  事务执行成功,之后的结果是持久的,一直保持

 

3、 事务配置方式

  1)  编程式事务

  编程式事务指的是通过编码方式实现事务,需要配置文件添加配置,并且在编码中也需要配置,现在使用越来越少

  2)  声明式事务

  建立在AOP之上的。对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务;声明式事务配置一般有五种(abcde),两种配置方式较为常用:我喜欢用第一种

    a)         使用AOP的方式实现事务配置

       

 

                      i.     aop:pointcut标签配置参与事务的类,由于是在Service中进行数据库业务操作,配的应该是包含那些作为事务的方法的Service类。

         首先应该特别注意的是id的命名,同样由于每个模块都有自己事务切面,所以我觉得初步的命名规则因为 all+模块名+ServiceMethod。而且每个模块之间不同之处还在于以下一句:

         expression="execution(* com.test.testAda.test.model.service.*.*(..))"

             其中第一个*代表返回值,第二*代表service下子包,第三个*代表方法名,“(..)”代表方法参数。

                      ii.   aop:advisor标签主要将事务属性配置和开启事务类进行关联

                      iii.    tx:attributes标签主要是配置事务的方法属性类型,name=add*中表示事务中所有以add开头的方法。

    b)         注解式配置

                      i.    Spring-mybatis

       

                      ii.  Spring-hibernata

       

                      iii.   注意@Transaction注解的使用

        这个注解只能使用在public方法上,别的不会报错,但是没有效果;如果这个注解放在类上,类里面的所有public方法都会有效。

                     iv.   全注解的使用方式

       

 

                      v.   注解中属性详解

        Propagation是传播属性,REQUIRED代表使用当前开启事务;rollbackFor=Exception.class代表出现异常回滚,可以指定多个异常;

        Timeout =1 事务的超时性;

        Isolation代表事务隔离级别,上面的是默认;

        配置readOnly=true表示当前事务为只读事务,如果为false为可读写,默认是false。

                     vi.   注解位置

        注解最好放在具体的类或者方法上,不要放在接口上,因为注解不具有继承性,所以如果读取不到注解信息,将不会读取到相应对象二进行事务配置。

    c)  每个bean都有一个代理

      https://blog.csdn.net/hjm4702192/article/details/17277669

    d)  所有bean共享一个代理基类

      https://blog.csdn.net/hjm4702192/article/details/17277669

    e)  使用拦截器

      https://blog.csdn.net/hjm4702192/article/details/17277669

4、 事务隔离级别

  事务隔离级别指的是多个并发事务之间的隔离程度

  1)  ISOLATION_DEFAULT

    此种隔离级别是事务管理默认配置的,使用数据库的默认隔离级别,上面的配置中就是使用此种级别,下面的四种级别与jdbc的相对应。

  2)  ISOLATION_READ_UNCOMMITTED

    未提交读。允许其他事务可以看到本事务未提交的数据,可造成脏读、幻读和不可重复读

  3)  ISOLATION_READ_COMMITTED

    提交读。其他事务只能读取到本事务提交后的数据,本事务不提交,其他事务无法读取到本事务数据,可防止脏读,可能出现幻读和不可重复读

  4)  ISOLATION_REPEATABLE_READ

    可重复度。保证事务不提交就不会读取到其数据,防止脏读和不可重复读,可能发生幻读

  5)  ISOLATION_SERIALIZABLE

    可串行化。牺牲效率顺序执行事物,如果事物执行异常,其他事务阻塞。防止脏读,幻读和不可重复。

5、 事务传播属性

  1)  PROPAGATION_REQUIRED

    使用当前事务,如果当前无事务,新建一个事务

  2)  PROPAGATION_SUPPORTS

    使用当前事务,如果当前无事务,使用非事务方式执行

  3)  PROPAGATION_MANDATORY

    使用当前事务,如果当前无事务,抛出异常

  4)  PROPAGATION_REQUIRES_NEW

    每次执行新建事务,如果当前存在事务,将当前事务挂起

  5)  PROPAGATION_NOT_SUPPORTED

    以非事务方式执行,如果当前存在事务,将当前事务挂起

  6)  PROPAGATION_NEVER

    以非事务方式执行,如果当前存在事务,抛出异常

  7)  PROPAGATION_NESTED

    嵌套类事务,如果当前存在事务,则在当前事务内新建事务并执行,如果当前无事务,与第一条同样方式执行

二、数据库隔离级别

         1、未提交读

    (Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

         2、提交读

    (Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

         3、可重复度

    (Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读

         4、可串行化

               (Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

三、数据异常

         1、脏读

               A事务正在添加zhangsan信息,但是还没提交,数据库就已经能读取到张三信息。

         2、幻读

    多个事务同时修改同一条记录,事务之间不知道彼此存在,当事务提交之后,后面的事务修改的数据将会覆盖前事务,前一个事务就像发生幻觉一样

                   例如:同时修改某行数据

          事务A将姓名字段修改为zhangsan,

                              事务B将姓名字段修改为lisi

                              事务提交,事务B将覆盖A数据,也就是zhangsan丢失。                

         3、不可重复读

              在A事务中,两次读取同一个数据,在A事务第一次读取数据之后,B事务修改这条数据,当A事务再次读取这条数据之后,获取到的结果与第一次读到的不一致。(读取到的数据不一致)

 

 

       事务完成操作之前,不允许其他事务进行操作,可避免

posted @ 2018-05-28 17:09  麻辣香蕉  阅读(2687)  评论(0编辑  收藏  举报