springboot 事务

一、隔离级别

1. 并发产生的问题

  • 脏读:一个事务读到了另一个未提交事务修改过的数据
  • 幻读:一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来。
  • 不可重复读:一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每次对该数据进行一次修改并提交后,该事务都能查询得到最新值

2. 事务隔离级别

  • 读未提交(Read Uncommitted):并发下,A事务可以读取到B事务未提交过的数据。容易发生脏读、幻读、不可重复读的线像。一版情况下数据库不会使用该隔离级别。
  • 读已提交(Read Committed):并发下,A事务比B事务开始执行,B事务如果要读取自己修改的数据,只能在A事务完成修改后已提交后,才能读取到。解决了脏读的问题,但可能发生幻读和不可重复读现像。
  • 可重复读(Repeatable Read):并发下,B事务若想读到自己修改的数据,只能在A事务修改过数据并提交后,自己也提交事务后,才能读取到。及解决了脏堵、幻读的问题,单可能发生不可重复读。
  • 可串行化(Serializable):并发下,最为严格的事务级别,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现。但是执行效率低下,一般不采用。

隔离级别级别越高对于数据库的性能影响越大:可串行化>可重复读>读已提交>读未提交
MySQL和Spring中默认的事务隔离级别是“读已提交”。

二 事务传播

事务的传播行为主要分为七种。

  • PROPAGATION_REQUIRED: 如果执行时,已经在一个事务中,就加入该事务。否则就开启一个新的事务。是默认的事务传播行为
  • PROPAGATION_SUPPORTS:如果执行时,已经在一个事务中,就加入该事务。没有的话,就不以事务的方式进行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。
  • PROPAGATION_MANDATORY:如果执行中,已经在一个事务中,就不能发起自己的事务。如果没有在一个事务中,就抛出异常。
  • PROPAGATION_REQUIRES_NEW:如果执行中,已经在一个事务中,则这个事务将被挂起。并开启一个事务执行当前业务方法。执行完毕后,回复原来挂起的事务继续进行。
  • PROPAGATION_NOT_SUPPORTED :总是非事务地执行,并挂起任何存在的事务。
  • PROPAGATION_NEVER :总是非事务地执行,如果存在一个活动事务,则抛出异常。
  • PROPAGATION_NESTED :如果业务方法在一个既有的事务中执行,则该业务方法将在一个嵌套的事务中进行;否则,按照TransactionDefinition.PROPAGATION_REQUIRED来对待。它使用一个单独的事务,这个事务可以有多个rollback点,内部事务的rollback对外部事务没有影响,但外部事务的rollback会导致内部事务的rollback。这个行为只对DataSourceTransactionManager有效。

三 SpringBoot中事务的配置

@Transactional源码

@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
    // 事务执行默认值
    @AliasFor("transactionManager")
    String value() default "";
    
    // 事务执行默认值
    @AliasFor("value")
    String transactionManager() default "";

    // 事务的传播级别
    Propagation propagation() default Propagation.REQUIRED;

    // 事务的隔离级别,默认的是读已提交
    Isolation isolation() default Isolation.DEFAULT;

    // 事务超时时长,-1代表永不超时
    int timeout() default -1;
    
    // 是否设置为只读的事务
    boolean readOnly() default false;

    // 设置需要进行回滚的异常类数组
    Class[] rollbackFor() default {};

    // 设置需要进行回滚的异常类名称数组
    String[] rollbackForClassName() default {};

    // 用于设置不需要进行回滚的异常类数组
    Class[] noRollbackFor() default {};

    // 用于设置不需要进行回滚的异常类名称数组
    String[] noRollbackForClassName() default {};
}

你可能感兴趣的:(springboot 事务)