事务隔离级别和Spirng事务传播级别

本文最后更新于:2020年9月10日 下午

事务的四个特性(ACID)

原子性

一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简

隔离性

数据库允许多个并发事务同时对其数据进行读写修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读已提交(read committed)、可重复读(repeatable read)和串行化/序列化(Serializable)。

一致性

在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。

持久性

事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

事务的隔离级别

读未提交:read uncommited

  • 产生的问题:脏读、幻读、不可重复读
  • 解决的问题:null

读已提交:read commited

  • 产生的问题:幻读、不可重复读
  • 解决的问题:脏读

可重复读:repeatable read

  • 产生的问题:幻读
  • 解决的问题:脏读、不可重复读

串行化(序列化):serializable

  • 产生的问题:null
  • 解决的问题:All
  • 隔离级别最高,效率最低

脏读、幻读、不可重复读

1. 脏读

一个事务读到了另一个事务未提交的数据(回滚)

2. 幻读

是不可重复读的一种特殊场景:当事务1两次执行SELECT … WHERE检索一定范围内数据的操作中间,事务2在这个表中创建了(如INSERT)了一行新数据,这条新数据正好满足事务1的“WHERE”子句。

给人的感觉就像出现了幻觉一样,之前明明不存在的数据,现在突然出现了,被称为“幻读”。

3. 不可重复读

第一个事务两次“读取”过程中,另一个事务对同样的数据进行更新,第一个事务两次读取结果不一致,所以被称为“不可重复读”。

数据库默认隔离级别

  1. mysql:repeatable read(可重复读
  2. Oracle:read commited(读已提交

事务的传播级别

  • MANDATORY:(mandatory:强制性) 以使用当前的事务,如果没有事务,抛出异常
  • REQUERS_NEW:(requers_new)新建一个事务,如果存在事务,则挂起之前的事务
  • REQUIRED:(required)(增删改)如果没有事务,则新建一个事务;如果事务,加入这个事务当中
  • NESTED:(nested:嵌套)事务,嵌套执行,没有事务,执行required
  • SUPPORTS:(supports)如果没有事务,非事务执行,如果事务,加入这个事务当中
  • NOT_SUPPORTED:(not_supported)必须非事务执行,如果事务,则挂起事务
  • NEVER:(never)非事务执行,如果存在事务,抛出异常