spring 事务管理

一、什么是事务

    咱们在开发时,会对数据进行持久化操做,如存入数据库中。当咱们操做数据库中的数据,后续可能会发生错误,抛出异常,前面对数据库的操做就会不可靠,在这种状况下须要回滚。spring

    事务的做用就是保证在事务中每一步操做都是可靠的,每一步操做均可以成功执行,中途出现错误或异常都要还原到事务开始前的状态。数据库

二、数据事务四种隔离机制和七种传播行为

2.1四种隔离机制

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别能够逐个解决脏读、不可重复读、幻读这几类问题。数组

  •  ISOLATION_READ_UNCOMMITTED(读取未提交内容):在该隔离级别,全部事务均可以看到其余未提交事务的执行结果。本隔离级别不多用于实际应用,由于它的性能也不比其余级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
  • ISOLATION_READ_COMMITTED(读取提交内容):这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它知足了隔离的简单定义:一个事务只能看见已经提交事务所作的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),由于同一事务的其余实例在该实例处理其间可能会有新的commit,因此同一select可能返回不一样结果。
  • ISOLATION_REPEATABLE_READ(可重读):这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到一样的数据行。不过理论上,这会致使另外一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另外一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎经过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
  • ISOLATION_SERIALIZABLE(可串行化) : 这是最高的隔离级别,它经过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每一个读的数据行上加上共享锁。在这个级别,可能致使大量的超时现象和锁竞争。

名词解释:并发

  • 脏读(Drity Read):某个事务已更新一份数据,另外一个事务在此时读取了同一份数据,因为某些缘由,前一个RollBack了操做,则后一个事务所读取的数据就会是不正确的。性能

  • 不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这多是两次查询过程当中间插入了一个事务更新的原有的数据。this

  •  幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例若有一个事务查询了几列(Row)数据,而另外一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

spring 中的实现:spa

public enum Isolation {
    // 底层数据库默认的隔离等级
    DEFAULT(-1),
    // 一个事务能够读取另外一个事务修改但尚未提交的数据。
    READ_UNCOMMITTED(1),
    // 该隔离级别表示一个事务只能读取另外一个事务已经提交的数据。
    READ_COMMITTED(2),
    // 该隔离级别表示一个事务在整个过程当中能够屡次重复执行某个查询,而且每次返回的记录都相同。即便在屡次查询之间有新增的数据知足该查询,这些新增的记录也会被忽略。
    REPEATABLE_READ(4),
    // 全部的事务依次逐个执行,这样事务之间就彻底不可能产生干扰,也就是说,该级别能够防止脏读、不可重复读以及幻读。
    SERIALIZABLE(8);

    private final int value;

    private Isolation(int value) {
        this.value = value;
    }

    public int value() {
        return this.value;
    }
}


2.2 七种传播行为

        2.2.1    PROPAGATION_REQUIRED:若是当前没有事务,就建立一个新事务,若是当前存在事务,就加入该事务,该设置是最经常使用的设置。代理

        2.2.2    PROPAGATION_SUPPORTS:支持当前事务,若是当前存在事务,就加入该事务,若是当前不存在事务,就以非事务执行。code

        2.2.3     PROPAGATION_MANDATORY:支持当前事务,若是当前存在事务,就加入该事务,若是当前不存在事务,就抛出异常。对象

        2.2.4    PROPAGATION_REQUIRES_NEW:建立新事务,不管当前存不存在事务,都建立新事务。

        2.2.5    PROPAGATION_NOT_SUPPORTED:以非事务方式执行操做,若是当前存在事务,就把当前事务挂起。

        2.2.6    PROPAGATION_NEVER:以非事务方式执行,若是当前存在事务,则抛出异常。

        2.2.7    PROPAGATION_NESTED:若是当前存在事务,则在嵌套事务内执行。若是当前没有事务,则执行与PROPAGATION_REQUIRED相似的操做。

    spring的实现:

public enum Propagation {

    // 若是当前存在事务,则加入该事务;若是当前没有事务,则建立一个新的事务。
    // @Transactional 注解默认采用这个方案
    REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

    // 若是当前存在事务,则加入该事务;若是当前没有事务,则以非事务的方式继续运行。
    SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

    // 若是当前存在事务,则加入该事务;若是当前没有事务,则抛出异常。
    MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

     // 建立一个新的事务,若是当前存在事务,则把当前事务挂起。
    REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

    // 以非事务方式运行,若是当前存在事务,则把当前事务挂起。
    NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

    // 以非事务方式运行,若是当前存在事务,则抛出异常。
    NEVER(TransactionDefinition.PROPAGATION_NEVER),

    // 若是当前存在事务,则建立一个事务做为当前事务的嵌套事务来运行;若是当前没有事务,则该取值等价于REQUIRED
    // 并不是全部的TransactionManager都能支持这个传播级别
    NESTED(TransactionDefinition.PROPAGATION_NESTED);

    private final int value;

    Propagation(int value) { this.value = value; }

    public int value() { return this.value; }

}

三、@Transactional注解中经常使用参数说明

@Transactional注解中经常使用参数说明

参数名称

功能描述

readOnly

该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)

rollbackFor

该属性用于设置须要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:

指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)

指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

rollbackForClassName

该属性用于设置须要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:

指定单一异常类名称:@Transactional(rollbackForClassName="RuntimeException")

指定多个异常类名称:@Transactional(rollbackForClassName={"RuntimeException","Exception"})

noRollbackFor

该属性用于设置不须要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:

指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)

指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})

noRollbackForClassName

该属性用于设置不须要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:

指定单一异常类名称:@Transactional(noRollbackForClassName="RuntimeException")

指定多个异常类名称:

@Transactional(noRollbackForClassName={"RuntimeException","Exception"})

propagation

该属性用于设置事务的传播行为,具体取值可参考表6-7。

例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)

isolation

该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的状况,一般使用数据库的默认隔离级别便可,基本不须要进行设置

timeout

该属性用于设置事务的超时秒数,默认值为-1表示永不超时

 

注意的几点:

  • Propagation.REQUIRED内嵌套Propagation.REQUIRES_NEW时,它们注释的方法必需要在不一样的类中,不然Propagation.REQUIRES_NEW不会生效。
  • @Transactional 只能被应用到public方法上, 对于其它非public的方法,若是标记了@Transactional也不会报错,但方法没有事务功能.
  • 用 spring 事务管理器,由spring来负责数据库的打开,提交,回滚.默认遇到运行期例外(throw new RuntimeException("注释");)会回滚,即遇到不受检查(unchecked)的例外时回滚;而遇到须要捕获的例外(throw new Exception("注释");)不会回滚,即遇到受检查的例外(就是非运行时抛出的异常,编译器会检查到的异常叫受检查例外或说受检查异常)时,需咱们指定方式来让事务回滚要想全部异常都回滚,要加上 @Transactional( rollbackFor={Exception.class,其它异常}) .若是让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
    以下:
@Transactional(rollbackFor=Exception.class) //指定回滚,遇到异常Exception时回滚
public void methodName() {
   throw new Exception("注释");
}
@Transactional(noRollbackFor=Exception.class)//指定不回滚,遇到运行期例外(throw new RuntimeException("注释");)会回滚
public ItimDaoImpl getItemDaoImpl() {
   throw new RuntimeException("注释");
}
  • @Transactional 注解应该只被应用到 public 可见度的方法上。 若是你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 可是这个被注解的方法将不会展现已配置的事务设置。
  • @Transactional 注解能够被应用于接口定义和接口方法、类定义和类的 public 方法上。然而,请注意仅仅 @Transactional 注解的出现不足于开启事务行为,它仅仅 是一种元数据,可以被能够识别 @Transactional 注解和上述的配置适当的具备事务行为的beans所使用。上面的例子中,其实正是 元素的出现 开启 了事务行为。
  • Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。你固然能够在接口上使用 @Transactional 注解,可是这将只能当你设置了基于接口的代理时它才生效。由于注解是不能继承的,这就意味着若是你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,并且对象也将不会被事务代理所包装(将被确认为严重的)。所以,请接受Spring团队的建议而且在具体的类上使用 @Transactional 注解。
相关文章
相关标签/搜索