zoukankan      html  css  js  c++  java
  • Spring声明式事务的隔离级别和传播机制

    声明式事务

    在Spring中,声明式事务是用事务参数来定义的。一个事务参数就是对事务策略应该如何应用到某个方法的一段描述,如下图所示一个事务参数共有5个方面组成:

    传播行为

    事务的第一个方面是传播行为。传播行为定义关于客户端和被调用方法的事务边界。Spring定义了7中传播行为。

    传播行为意义
    PROPAGATION_MANDATORY 表示该方法必须运行在一个事务中。如果当前没有事务正在发生,将抛出一个异常
    PROPAGATION_NESTED 表示如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中。被嵌套的事务可以独立于封装事务进行提交或回滚。如果封装事务不存在,行为就像PROPAGATION_REQUIRES一样。
    PROPAGATION_NEVER 表示当前的方法不应该在一个事务中运行。如果一个事务正在进行,则会抛出一个异常。
    PROPAGATION_NOT_SUPPORTED 表示该方法不应该在一个事务中运行。如果一个现有事务正在进行中,它将在该方法的运行期间被挂起。
    PROPAGATION_SUPPORTS 表示当前方法不需要事务性上下文,但是如果有一个事务已经在运行的话,它也可以在这个事务里运行。
    PROPAGATION_REQUIRES_NEW 表示当前方法必须在它自己的事务里运行。一个新的事务将被启动,而且如果有一个现有事务在运行的话,则将在这个方法运行期间被挂起。
    PROPAGATION_REQUIRES 表示当前方法必须在一个事务中运行。如果一个现有事务正在进行中,该方法将在那个事务中运行,否则就要开始一个新事务。

    传播规则回答了这样一个问题,就是一个新的事务应该被启动还是被挂起,或者是一个方法是否应该在事务性上下文中运行。

    spring(数据库)事务隔离级别分为四种(级别递减):

    1、Serializable (串行化):最严格的级别,事务串行执行,资源消耗最大;

    2、REPEATABLE READ(重复读) :保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但不能避免“幻读”,但是带来了更多的性能损失。

    3、READ COMMITTED (提交读):大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”,但不能避免“幻读”和“不可重复读取”。该级别适用于大多数系统。

    4、Read Uncommitted(未提交读) :事务中的修改,即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读取”。

    脏读、不可重复读、幻读:

    也许有很多读者会对上述隔离级别中提及到的 脏读、不可重复读、幻读 的理解有点吃力,我在这里尝试使用通俗的方式来解释这三种语义:

    脏读:所谓的脏读,其实就是读到了别的事务回滚前的脏数据。比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。

    也就是说,当前事务读到的数据是别的事务想要修改成为的但是没有修改成功的数据。

    不可重复读:事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。

    也就是说,当前事务先进行了一次数据读取,然后再次读取到的数据是别的事务修改成功的数据,导致两次读取到的数据不匹配,也就照应了不可重复读的语义。

    幻读:事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。

    也就是说,当前事务读第一次取到的数据比后来读取到数据条目少。

    不可重复读和幻读比较:

    两者有些相似,但是前者针对的是update或delete,后者针对的insert。

    <!-- 4. 配置声明式事务    引入名称空间-->
        <tx:advice id="txAdvice" transaction-manager="txManager">
          <tx:attributes>
            <!-- 指定所有的get开头的方法都是只读的不进行声明式事务管理 -->
            <tx:method name="get*" read-only="true"/>
            <!-- 指定其他的方法均要进行事务管理 
                 rollback-for属性指定事务在什么情况下进行回滚
                 propagation属性指定事务的传播特性REQUIRED 用service事务|REQUIRES_NEW用dao层的事务
                 isolation属性指定事务的隔离级别,一般的数据库(mysql orecle等)都是"READ_COMMITTED" 可以不做设置
            -->
            <tx:method name="*" propagation="REQUIRED" rollback-for="" isolation="READ_COMMITTED"/>
          </tx:attributes>
        </tx:advice>
  • 相关阅读:
    Oracle 与.NET Framework 数据类型映射
    mvc使用JsonResult返回Json数据(转)
    like参数替换
    jquery 等比缩放
    【linq to sql】已有打开的与此命令相关联的 DataReader,必须首先将它关闭
    脚本
    2012年计划——开始我的敏捷个人之行
    在Win7 64位机器上安装Oracle 10客户端以及PlSql
    词干提取算法Porter Stemming Algorithm解读
    开源搜索框架Lucene学习之分词器(2)——TokenFilter类及其子类
  • 原文地址:https://www.cnblogs.com/Eddyer/p/10282713.html
Copyright © 2011-2022 走看看