数据库事务隔离级别

前言

在数据库中,隔离级别分为四种不同的级别,不同的级别分别解决不同的问题,脏读,不可重复读,幻读。隔离级别越高,数据库的并发性能越低。

事务ACID特性

  • 原子性(Atomicity)

    事务是数据库执行的基本单位,事务中包含的操作要么全部执行,要么全部不执行(支持事务的commit和rollback)。

  • 一致性(Consistency)

    指事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。可理解为业务数据的一致。

  • 隔离性(Isolation)

    指多个事务并发执行的时候相互之间不受到彼此的干扰,但是考虑到并发性能,将隔离级别分为四种不同级别,隔离级别越高,并发性能越低。通常,在工程实践中,为了性能的考虑会对隔离性进行折中。

  • 持久性(Durability)

    事务一旦提交成功,数据库中数据的改变应该是持久性的,不会因为断电等丢失数据。

事务隔离级别

  • 读未提交(Read uncommitted)

    一个事务可以读取其他事务还未提交的数据,这个级别会导致脏读。工程实践中基本不会使用此级别。

  • 读已提交(Read committed)

    一个事务可以读取其他事务已经提交的数据,此隔离级别可以解决脏读的问题。但是存在不可重复读的问题。大多数数据库默认的隔离级别都是此级别(oracle,sql server等)

    所谓不可重复读,是指A,B两个事务,其中A事务第一次读取账户余额为2000,这时事务B从账户余额中转账1000并提交了事务,在同一个事务A中,再次读取账户发现余额变为了1000,不是之前的2000了,产生了不重复可读的现象。

  • 可重复读(Repeatable read)

    可重复读隔离级别,通过存储引擎的锁机制,解决了不可重复读的问题,但是无法解决幻读的问题,所谓幻读,是指当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入或删除记录,当之前的事务再次读取该范围内的记录时,会产生幻行,记录总数跟之前的不对(mysql默认的隔离级别是可重复读)。

  • 串行化(Serializable)

    串行化隔离级别,就是多个事务串行化一个个按照顺序执行,这种不存在并发情况,所以可以避免所有事务并发问题。

总结

隔离级别:读未提交(Read uncommitted) < 读已提交(Read committed) < 可重复读(Repeatable read) < 串行化(Serializable)

隔离级别越高,数据库并发性能越低,数据库通过锁机制,MVCC并发控制来实现不同的隔离级别,锁按粒度不同可划分为表级锁,间隙锁,行级锁;按类型不同可划分为共享锁S和排他锁X

不可重复读强调的是同一个事务中对同一行记录的多次查询,结果不一致。

幻读强调的是同一个事务中多次查询某个范围内的记录数,结果不一致。

参考链接

  1. http://www.hollischuang.com/archives/943
  2. http://ifeve.com/%E5%AE%9E%E6%88%98spring%E4%BA%8B%E5%8A%A1%E4%BC%A0%E6%92%AD%E6%80%A7%E4%B8%8E%E9%9A%94%E7%A6%BB%E6%80%A7/